thrift數據類型

1 前言

  Thrift是facebook技術核心框架之一,不同開發語言開發的服務可以通過該框架實現通信。Thrift通過接口定義語言 (interface definition language,IDL) 來定義數據類型和服務,Thrift接口定義文件由Thrift代碼編譯器生成thrift目標語言的代碼(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),並由生成的代碼負責RPC協議層和傳輸層的實現。

  簡而言之,開發者只需準備一份thrift腳本,通過thrift code generator(像gcc那樣輸入一個命令)就能生成所要求的開發語言代碼。不支持windows。

  Thrift側重點是構建跨語言的可伸縮的服務,特點就是支持的語言多,同時提供了完整的RPC service framework,可以很方便的直接構建服務,不需要做太多其他的工作。服務端可以根據需要編譯成simple | thread-pool | threaded | nonblocking等方式;

  本文檔參考:Thrift typesThrift IDL, Thrift:The Missing Guide.

2 語法參考

 2.1 類型

  Thrift類型系統包括預定義基本類型,用戶自定義結構體,容器類型,異常和服務定義。

 2.1.1 基本類型

  • bool: 布爾值 (true or false), one byte

  • byte: 有符號字節

  • i16: 16位有符號整型

  • i32: 32位有符號整型

  • i64: 64位有符號整型

  • double: 64位浮點型

  • string: Encoding agnostic text or binary string

Note that: Thrift不支持無符號整型,因爲Thrift目標語言沒有無符號整型,無法轉換。

 2.1.2 容器(Containers)

  Thrift容器與流行編程語言的容器類型相對應,採用Java泛型風格。它有3種可用容器類型:

  • list<t1>: 元素類型爲t1的有序表,容許元素重複。(有序表ordered list不知道如何理解?排序的?c++的vector不排序)

  • set<t1>:元素類型爲t1的無序表,不容許元素重複。

  • map<t1,t2>: 鍵類型爲t1,值類型爲t2的kv對,鍵不容許重複。

  容器中元素類型可以是除了service外的任何合法Thrift類型(包括結構體和異常)。

 2.1.3 結構體和異常(Structs and Exceptions)

  Thrift結構體在概念上類似於(similar to)C語言結構體類型--將相關屬性封裝在一起的簡便方式。Thrift結構體將會被轉換成面嚮對象語言的類。

  異常在語法和功能上類似於(equivalent to)結構體,差別是異常使用關鍵字exception而不是struct聲明。但它在語義上不同於結構體:當定義一個RPC服務時,開發者可能需要聲明一個遠程方法拋出一個異常。

  結構體和異常的聲明將在下一節介紹。

 2.1.4 服務(Services)

  服務的定義方法在語義(semantically)上等同於面嚮對象語言中的接口。Thrift編譯器會產生執行這些接口的client和server stub。具體參見下一節。

 2.2 類型定義(Typedef)

  Thrift支持C/C++類型定義。

  typedef i32 MyInteger // a  typedef T ReT // b

  說明:a.  末尾沒有逗號。b.   struct也可以使用typedef。

 2.3 枚舉(Enums)

  很多語言都有枚舉,意義都一樣。比如,當定義一個消息類型時,它只能是預定義的值列表中的一個,可以用枚舉實現。

enum TweetType {TWEET, // (1)   RETWEET = 2// (2)DM = 0xa// (3)   REPLY} // (4)struct Tweet {1: required i32 userId;2: required string userName;3: required string text;4: optional Location loc;5: optional TweetType tweetType = TweetType.TWEET; // (5)16: optional string language = "english"}

  說明:

  (1).  編譯器默認從0開始賦值

  (2).  可以賦予某個常量某個整數

  (3).  允許常量是十六進制整數

  (4).  末尾沒有分號

  (5).  給常量賦缺省值時,使用常量的全稱

  注意,不同於protocal buffer,thrift不支持枚舉類嵌套,枚舉常量必須是32位的正整數

 2.4 註釋(Comment)

  Thrift支持shell風格, C多行風格和Java/C++單行風格。

# This is a valid comment.// C++/Java style single-line comments work just as well.

 2.5 名字空間(Namespace)

  Thrift中的命名空間類似於C++中的namespace和java中的package,它們提供了一種組織(隔離)代碼的簡便方式。名字空間也可以用於解決類型定義中的名字衝突。

  由於每種語言均有自己的命名空間定義方式(如python中有module), thrift允許開發者針對特定語言定義namespace:  

namespace cpp com.example.project // (1)namespace java com.example.project // (2)namespace php com.example.project

  (1). 轉化成namespace com { namespace example { namespace project {

  (2).  轉換成package com.example.project


 2.6 Includes

  便於管理、重用和提高模塊性/組織性,我們常常分割Thrift定義在不同的文件中。包含文件搜索方式與c++一樣。Thrift允許文件包含其它thrift文件,用戶需要使用thrift文件名作爲前綴訪問被包含的對象,如:

include "tweet.thrift" // (1)...struct TweetSearchResult {1: tweet.Tweet tweet; // (2)}

  說明:

  (1).  thrift文件名要用雙引號包含,末尾沒有逗號或者分號

  (2).  注意tweet前綴

 2.7 常量(Constant)

  Thrift允許定義跨語言使用的常量,複雜的類型和結構體可使用JSON形式表示。

const i32 INT_CONST = 1234// (1)

  說明:

  (1) 分號可有可無。支持16進制。

 2.8 結構體定義(Defining Struct)

  struct是Thrift IDL中的基本組成塊,由域組成,每個域有唯一整數標識符,類型,名字和可選的缺省參數組成。如定義一個類似於Twitter服務:

struct Tweet {1: required i32 userId; // (1)2: required string userName; // (2)3: required string text;4: optional Location loc; // (3)16: optional string language = "english" // (4)}struct Location { // (5)1: required double latitude;2: required double longitude;}

 (1) 每個域有一個唯一的正整數標識符;

 (2) 每個域可標識爲required或optional;

 (3) 結構體可以包含其它結構體

 (4) 域可有默認值,與required或optional無關。

 (5) Thrift文件可以定義多個結構體,並在同一文件中引用,也可加入文件限定詞在其它Thrift文件中引用。

  如上所見,消息定義中的每個域都有一個唯一數字標籤,這些數字標籤在傳輸時用來確定域,一旦使用消息類型,標籤不可改變。(隨着項目的進展,可以要變更Thrift文件,最好不要改變原有的數字標籤

  規範的struct定義中的每個域均會使用required或者optional關鍵字進行標識。如果required標識的域沒有賦值,Thrift將給予提示;如果optional標識的域沒有賦值,該域將不會被序列化傳輸;如果某個optional標識域有缺省值而用戶沒有新賦值,則該域的值一直爲缺省值;如果某個optional標識域有缺省值或者用戶已經重新賦值,而不設置它的__isset爲true,也不會被序列化傳輸。(不被序列化傳輸的後果是什麼?爲空爲零?還是默認值,下次試試)

  與services不同,結構體不支持繼承。

2.9 服務定義(Defining Services)

  在流行的序列化/反序列化框架(如protocal buffer)中,Thrift是少有的提供多語言間RPC服務的框架。這是Thrift的一大特色。

  Thrift編譯器會根據選擇的目標語言爲server產生服務接口代碼,爲client產生stubs。

service Twitter {// A method definition looks like C code. It has a return type, arguments,// and optionally a list of exceptions that it may throw. Note that argument// lists and exception list are specified using the exact same syntax as// field lists in structs.void ping(), // (1)bool postTweet(1:Tweet tweet); // (2)TweetSearchResult searchTweets(1:string query); // (3)// The 'oneway' modifier indicates that the client only makes a request and// does not wait for any response at all. Oneway methods MUST be void.oneway void zip() // (4)}
 (1) 有點亂,接口支持以逗號和分號結束;
 (2) 參數可以是基本類型和結構體;(參數是cosnt的,轉換爲c++語言是const&)
 (3) 返回值同參數一樣;
 (4) 返回值是void,注意oneway;

Note that:參數列表的定義與結構體一樣。服務支持繼承。

 

源地址:http://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167669.html 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章