thrift接口描述語言(IDL)用來定義thrift類型. 一個Thrift IDL文件用來生成各類語言使用的結構體和服務.php
IDL中包含以下部分:java
1. Documentgit
Document中包含0或者多條以下的聲明:golang
(1) include Literal編程
Thrift Include: 用來導入其餘thrift中的符號, 在這個thrift中使用導入的thrift中的符號時, 須要帶一個前綴.這個thrift編譯時, 被導入thrift的對應頭文件會被插入到這個thrift編譯的相應文件中.服務器
說明: Literal表示字符串常量, 寫法要求有可選值(其中*表示0或者多個字符):編程語言
1) 「[^」]*」 (其中[^」]表示不爲雙引號的字符)函數
2) ‘[^’]*’ (其中[^’]表示不爲單引號的字符)ui
示例: include "xxx.thrift" this
(2) cpp_include Literal
C++ Include: 用來在這個thrift編譯生成的文件中添加Literal頭文件.
示例: cpp_include "xxx.h"
(3) namespace NamespaceScope Identifier
Namespace: 一個namespace表示一個命名空間/包/模塊等, 含義基於編譯成的目標語言, 其中在C++中表示命名空間名, 在golang中表示包名. NamespaceScope表示對應的編程語言, 若是使用*, 則表示對全部的語言都使用一樣的Namespace名.
說明:
(1) NamespaceScope可使用以下值取代: *, c_glib, cpp, csharp, delphi, go, java, js, lua, netcore, perl, php, py, py.twisted, rb, st, xsd.
(2) Identifier容許的寫法(其中|表示或的關係, *表示出現0次或者屢次): (Letter|_)(Letter | Digit | . | _ | -)*.
(3) Letter表示A-Z或者a-z中的一個字符.
(4) Digit表示0-9中的一個數字.
示例: namespace cpp tutorial
2. Definition
Definition包含以下的多條定義:
(1) const FieldType Identifier = ConstValue ListSeparator?
說明: ?表示可選, 其中ListSeparator包括兩個可選值: (1) ,(逗號) (2);(分號)
用來定義一個常量, 能夠參考以下示例:
const i32 INT32CONSTANT = 9853 const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
(2) typedef DefinitionType Identifier
用來定義一個類型的別名, 其中DefinitionType包括可選值: (1) BaseType (2) ContainerType, BaseType和ContainerType的說明見後文, 關於定義別名, 能夠參考以下示例:
typedef i32 MyInteger
(3) enum Identifier { (Identifier (= IntConstant)? ListSeparator?)* }
說明: 其中的*表示多條
用來定義一個枚舉類型. 若是枚舉結構體內的標識符沒有提供常量, 那麼第一個元素取0, 對於後續元素會比前一個元素大1. 全部提供的常量都必須是非負的. 能夠參考以下示例:
enum Operation { ADD = 1, SUBTRACT = 2, MULTIPLY = 3, DIVIDE = 4 }
/** * Common status reporting mechanism across all services */ enum fb_status { DEAD = 0, STARTING = 1, ALIVE = 2, STOPPING = 3, STOPPED = 4, WARNING = 5, }
(4) senum Identifier { (Literal ListSeparator?)* }
注: 和slist都是deprecated, 都使用string來代替.
(5) struct Identifier { Field* }
用來定義複合類型, struct中的每一個成員名都須要是惟一的, 能夠參考以下示例:
struct Work { 1: i32 num1 = 0, 2: i32 num2, 3: Operation op, 4: optional string comment, }
(6) union Identifier { Field* }
用來定義union類型, union類型中的全部成員只有一個成員有值, 當設置另外一個成員時, 就只會有那個成員有值, 這個類型相似於C++中的union. 因此, union中的成員都默認爲可選的(查看requiredness). 能夠參考以下示例:
union Dessert { 1: string port 2: string iceWine }
(7) exception Identifier { Field* }
用來定義一個異常. exception中的每個成員都須要是惟一的.
/** * Structs can also be exceptions, if they are nasty. */ exception InvalidOperation { 1: i32 whatOp, 2: string why }
(8) service Identifier (extends Identifier)? { Function* }
用來定義使用thrift的服務器的函數接口. 一個服務能夠擴展(extend)其餘的服務, 那麼這個服務就能夠提供被擴展服務的函數接口. 關於服務的一個簡單示例:
/** * Standard base service */ service FacebookService { /** * Returns a descriptive name of the service */ string getName(), /** * Returns the version of the service */ string getVersion(), /** * Gets the status of this service */ fb_status getStatus(), /** * User friendly description of status, such as why the service is in * the dead or warning state, or what is being started or stopped. */ string getStatusDetails(), /** * Gets the counters for this service */ map<string, i64> getCounters(), /** * Gets the value of a single counter */ i64 getCounter(1: string key), /** * Sets an option */ void setOption(1: string key, 2: string value), /** * Gets an option */ string getOption(1: string key), /** * Gets all options */ map<string, string> getOptions(), /** * Returns a CPU profile over the given time interval (client and server * must agree on the profile format). */ string getCpuProfile(1: i32 profileDurationInSec), /** * Returns the unix time that the server has been running since */ i64 aliveSince(), /** * Tell the server to reload its configuration, reopen log files, etc */ oneway void reinitialize(), /** * Suggest a shutdown to the server */ oneway void shutdown(), }
下面解釋一下上面出現的Field和Function.
Field
Field的定義以下:
IntConstant : FieldReq? FieldType Identifier (= ConstValue)? ListSeparator?
其中FieldReq可選值包括: (1) required (2) optional (3) 若是沒有指定, 則爲default.
(1) required表示這個字段是必需的.
(2) optional 表示這個字段是可選的.
大多數語言使用推薦的」isset」標誌來標示optional的成員有沒有被設置值.
(3) default
default是optional和required的混合,所以內部名爲」opt-in,req-out」. 雖然理論上這些字段都會被寫入(「req-out」), 實際上未被設置的字段老是不會寫入. 尤爲是, 結構體中的某個字段根據定義包含不能經過thrift發送的值. 這種狀況下,惟一可以採起的方式,就是根本不寫入這個值.
關於默認值特定要注意的是, 任何沒有顯示寫入的默認值, 會隨着接口定義而改變, 而將默認值寫入到output中, IDL改變默認值,不會對這個產生影響.
FieldType說明:
1. FieldType包括可選值: (1) Identifier (thrift中定義的struct, union等) (2) BaseType (3) ContainerType
2. BaseType包括可選值: bool, byte, i8, i16, i32, i64, double, string, binary, slist
3. ContainerType包括可選值:
(1) map (cpp_type Literal)? <FieldType, FieldType>
(2) set (cpp_type Literal)? <FieldType>
(3) list<FieldType> (cpp_type literal)?
ConstValue包括以下可選值(其中+號表示1個或者多個, |表示或的關係):
(1) IntConstant: (+ | -)? Digit+
(2) DoubleConstant: (+ | -)? Digit* (.Digit+)? ( (E | e) IntConstant)?
(3) ConstList: [ (ConstValue ListSeparator?)*]
(4) ConstMap: { (ConstValue : ConstValue ListSeparator?)* }
Function:
Function的定義格式: oneway? (FieldType | void) Identifier (Field*) (throws (Field*))? ListSeparator?
其中涉及的FieldType, Identifier, Field等的定義, 參考上面的說明.