FlatBuffers使用记录(Golang)
试用了下FlatBuffers,把一些东东记录一下。 FlatBuffers 官网: http://google.github.io/flatbuffers/md__go_usage.html 它支持生成Go语言相关的东西,总的使用步骤如下: 1. 定义IDL 接口定义文件,通常命名为.fbs参考: Writing a schema http://google.github.io/flatbuffers/md__schemas.html 2. 利用flatc 解析生成语言的文件 flatc 参考: Using the schema compiler http://google.github.io/flatbuffers/md__compiler.html 生成Go的参数: -g : Generate Go classes. Skipped for data. 3. 在Go工程中安装FlatBuffers的Go支持包,就可以在代码直接使用了.
再详细说说FlatBuffers的一些特性。先上一份.fbs的例子: // example IDL file namespace MyGame; attribute "priority"; enum Color : byte { Red = 1,Green,Blue } ///union Any { Monster,Weapon,Pickup } //union Any { Monster} union Any { Monster,Weapon} struct Vec3 { x:float; y:float; z:float; } /// 注释 table Monster { pos:Vec3; mana:short = 150; hp:short = 100; name:string; friendly:bool = false (deprecated,priority: 1); inventory:[ubyte]; color:Color = Blue; test:Any; } table Weapon { pos:Vec3; mana:short = 150; } root_type Monster; root_type Weapon;依上面的IDL作例子来说明一下. IDL生成结果: 会在MyGame下,生成Any.go,Color.go,Monster.go,Vec3.go,Weapon.go 5个go文件 protobuf则不会,protobuf会全部生成到一个.pb.go文件中.这么比起来,FlatBuffers灵活度更高些. 格式分析: "namespace MyGame;" : 会生成对应的MyGame目录 "mana:short = 150;" : 可以直接指定数据类型及默认值,且非常直观。 " table Monster { pos:Vec3; ": table可以直接嵌套struct "friendly:bool = false (deprecated,priority: 1);" : 通过指定deprecated,可以删除掉此字段。 attribute "priority" : 定义了priority关键字,用在friendly上,但从生成的Go文件来看,没看出有啥意义。 感觉可以忽略. "union Any { Monster,Weapon}" : union相关的东西用在 "test:Any;" 上. 生成一个Any.go文件,里面的内容: const ( AnyNONE = 0 AnyMonster = 1 AnyWeapon = 2 )可以看到相当于一个enum类型。 "root_type Monster;root_type Weapon;" root_type的作用: 在其table生成的go文件中,除Table中字段会生成相关函数外, 会另外生成GetRootAsMonster()函数,便于调用 func GetRootAsMonster(buf []byte,offset flatbuffers.UOffsetT) *Monster { 如不用也可,没有太大影响。 格式其它: 注释: 在FlatBuffers中用 " ///" 来表示。且此注释会带入到生成的源码文件中。 效验: 1. 当使用了未定义的类型或定义时,会报错 2. 依顺序解析,如把最末的root_type Monster;提到table Monster前面,也会报错 required/optional : struct的每个字段都为required table的每个字段都默认都是optional,但可以指定为required 指定Table字段函数生成顺序: /// 加id指定生成顺序 table Monster { pos:Vec3 (id: 0); mana:short = 150 (id: 3); hp:short = 100 (id: 1); name:string (id: 2); //friendly:bool = false (deprecated,priority: 1); friendly:bool = false (deprecated,id: 4); //friendly:bool = false (priority: 1); inventory:[ubyte] (id: 6); color:Color = Blue (id: 5); test:Any (id: 8); } 依此为例,会按id指定顺序生成相关函数.
支持.fbs文件的嵌套: 可以用include "include_test1.fbs"; 形式,将其它.fbs文件嵌套进来。 使用方法: 取值: buf,err := ioutil.ReadFile("monster.dat") offset := 0 monster := example.GetRootAsMonster(buf,offset) got := monster.Hp()直接得到即可。 赋值: 可参考此代码: builder := flatbuffers.NewBuilder(0) str := builder.CreateString("MyMonster") example.MonsterStart(builder) example.MonsterAddPos(builder,example.CreateVec3(builder,1.0,2.0,3.0,4,5,6)) example.MonsterAddHp(builder,80) example.MonsterAddName(builder,str) example.MonsterAddInventory(builder,inv) example.MonsterAddTestType(builder,1) // example.MonsterAddTest(builder,mon2) // example.MonsterAddTest4(builder,test4s) _ = example.MonsterEnd(builder) 就到这了,速度啥的没做对比。 总的感觉是FlatBuffers定义起来简单,直观。 对Go支持很好,特别是分别生成一个个对应.go文件这点比较爽。其它待看。 MAIL: xcl_168@aliyun.com BLOG:http://blog.csdn.net/xcl168 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |