thrift学习-idl

本文详细介绍了Thrift IDL,包括基本类型如bool、byte、struct、容器(list、set、map)、枚举、常量定义、异常、服务和命名空间的使用。Thrift的struct类似于面向对象的class,但不允许继承,容器类型与多种编程语言的容器对应,枚举用于预定义值列表,服务则转化为目标语言的接口。命名空间和包含(includes)提供了代码组织和重用的机制。

thrift-idl

1.基本类型

  • bool:布尔值(true or false),一个字节
  • byte:有符号字节
  • i16:16位有符号整型
  • i32:32位有符号整型
  • i64:64位有符号整型
  • double:64位浮点型
  • string:encoding agnostic text or binary string

thrift不支持无符号整型

2.特殊类型

  • binary:Blob(byte arrau) a sequence of unencoded bytes
    这是string类型的一种变形,主要是为java使用

3.struct

thrift中的struct是定义为一种对象,和面向对象语言的class差不多,但是struct有一下约束:

  • struct不能继承,但是可以嵌套,不能嵌套自己
  • 其他成员都是有明确类型
  • 成员是被正整数编号过的,其中编号不能重复。这是为了在传输过程中编码的使用
  • 成员分隔符可以是逗号(,)或者是分号(?,而且可以混用。在使用中一般只使用一种
  • 字段会有optional、required,也可以不指定。optional表示可选字段,如果不填充则不序列化;required是必填字段,如果不填充则报错,一定会序列化;不指定也表示可选字段,但是会序列化
  • 每个字段可以设置默认值
  • 同一个文件可以定义多个struct,也可以定义在不痛的文件中,进行include引入

数字标签作用非常大,但是随着项目的不断开发,也许字段会有变化,但是建议不要轻易修改这些字段,万一修改了一定要同步到服务器端、客户端

struct Report
{
	1: required string msg,  //必填字段,会序列化
	2: optional i32 type = 0, //不是必填字段,默认值为0.因为有默认值,所以相当于是必填字段,会序列化。如果没有默认值则不会序列化
	3: i32 time //没有默认值。不是必填,不管有没有填该字段,都会序列化
}

规范的struct定义中的每个域均会使用required或者 optional关键字进行标识。如果required标识的域没有赋值,Thrift将给予提示;如果optional标识的域没有赋值,该域将不会被序列化传输;如果某个optional标识域有缺省值而用户没有重新赋值,则该域的值一直为缺省值;如果某个optional标识域有缺省值或者用户已经重新赋值,而不设置它的__isset为true,也不会被序列化传输

4.容器(Containers)

thrift容器与目前流行变成语言的容器类型相对应,有三种可用容器类型:

  • list:元素类型为t的有序表,容许元素重复
  • set:元素类型为t的无需表,不容许元素重复
  • map<k,t>:键类型为k,值类型为t的kv对,键不容许重复

容器中的元素类型可用是除了service外的任何合法的thrift类型(包括结构体和异常)。为了最大的兼容性,map的key最好是thrift的基本类型,有些语言不支持复杂类型的key,JSON协议只支持那些基本类型的key。

5.枚举(enum)

很多语言都有枚举,意义都一样。比如,当定义一个消息类型时,它只能是预定义的值列表中的一个,可以用枚举实现

  • 编译器默认从0开始赋值
  • 可以赋予某个常量某个整数
  • 允许常量是十六进制整数
  • 末尾没有符号分割
  • 给常量赋缺省值时,使用常量的全称

枚举常量必须是32位的正整数

enum EnOpType {
  CMD_OK = 0, // (0)   
  CMD_NOT_EXIT = 2000, // (2000)
  CMD_EXIT = 2001, // (2001)    
  CMD_ADD = 2002 // (2002)
}

struct StUser {
  1: required i32 userId;
  2: required string userName;
  3: optional EnOpType cmd_code = EnOpType.CMD_OK; // (0)
  4: optional string language = “english”
}

6.常量定义和类型定义

thrift允许定义跨语言使用的常量,复杂的类型和结构体可用json形式表示

const i32 INT_CONST = 1234; 
const EnOpType myEnOpType = EnOpType.CMD_EXIT; //2001

7.异常(Exceptions)

thrift结构体将转换成面向对象语言的类
异常在语法和功能上类似于结构体,差别是异常使用关键字exception,而且异常是继承某种语言的基础异常类

exception Extest {
  1: i32 errorCode,
  2: string message,
  3: StUser userinfo
}

8.服务(Services)

服务的定义方法在语义上等同于面向对象语言中的接口。Thrift编译器会产生执行这些接口的client和server stub

Thrift编译器会根据选择的目标语言为server产生服务接口代码,为client产生stubs

service SeTest {
  void ping(),      
  bool postTweet(1: StUser user);
  StUser searchTweets(1:string name);
  oneway void zip()
}

thrift编译器编译后的c++代码

class SeTestIf {
  public:      
    virtual ~SeTestIf() {}
    virtual bool AddUser(const StUser& user) = 0;
    virtual void SearchUser(StUser& _return, const std::string& name) = 0;
    virtual void NopNop() = 0;
};

9.命名空间(Namespace)

thrift的命名空间类似于c++中的namespace和java中的package,它们提供了一种组织(隔离)代码的简便方式。名字空间也可以用于解决类型定义中的名字冲突。

由于每种语言均有自己的命名空间定义方式(如Python中有module), thrift允许开发者针对特定语言定义namespace:

namespace cpp com.example.test
namespace java com.example.test 
namespace php com.example.test  

11.Includes

便于管理、重用和提高模块性/组织性,我们常常分割Thrift定义在不同的文件中。包含文件搜索方式与c++一样。Thrift允许文件包含其它thrift文件,用户需要使用thrift文件名作为前缀访问被包含的对象,如:

include "test.thrift"   
...
struct StSearchResult {
    1: in32 uid; 
	...
}

thrift文件名要用双引号包含,末尾没有逗号或者分号

参考

【1】https://www.cnblogs.com/valor-xh/p/6386584.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值