go的go protobuf enum这个问题是不是一个bug

主题 : iphone上使用protobuf的问题
级别: 新手上路
可可豆: 250 CB
威望: 250 点
在线时间: 39(时)
发自: Web Page
来源于&&分类
iphone上使用protobuf的问题&&&
怎么编译出来一个可以在iphone上用的libProtocolBuffers.a望有经验的人指导。。。。【protobuf链接:】
级别: 精灵王
UID: 23111
可可豆: 3305 CB
威望: 4712 点
在线时间: 2010(时)
发自: Web Page
你这个通讯为什么搞这么复杂呢?上面的人要求?
级别: 新手上路
可可豆: 250 CB
威望: 250 点
在线时间: 39(时)
发自: Web Page
建立个lib工程,把protobuf的代码拷贝过来编译就可以了。网络部分用这个比较熟悉而且方便。
级别: 新手上路
可可豆: 11 CB
威望: 11 点
在线时间: 8(时)
发自: Web Page
你的问解决了没有。。。如果解决了 加下我Q
级别: 圣骑士
可可豆: 2725 CB
威望: 2725 点
在线时间: 614(时)
发自: Web Page
回 楼主(willreno) 的帖子
请问大侠typeName 怎么获取
级别: 新手上路
UID: 100229
可可豆: 47 CB
威望: 44 点
在线时间: 62(时)
发自: Web Page
有人解决了么? 如果解决了 加下我Q
一直觉得人应该去旅行,在年轻的时候,趁着有脾气装潇洒,有本钱耍个性,离开睁眼闭 ..
级别: 骑士
UID: 349054
可可豆: 970 CB
威望: 846 点
在线时间: 285(时)
发自: Web Page
回 2楼(willreno) 的帖子
紧急求助! 添加了ProtocolBuffers的obj c库后,报很多错&&
注册开发者账号终于提交信息成功,坐等邓氏来审核在线。。。。。。等
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版Protobuf数据格式解析 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了12587字,被11人关注,获得了23个喜欢
Protobuf数据格式解析
Protobuf是Google开源的一款类似于Json,XML数据交换格式,其内部数据是纯二进制格式,不依赖于语言和平台,具有简单,数据量小,快速等优点。目前用于序列化与反序列化官方支持的语言有C++,C#, GO, JAVA, PYTHON。适用于大小在1M以内的数据,因为像在移动设备平台,内存是很珍贵。
使用方法也比较简单:
定义用于消息文件.proto
使用protobuf的编译器编译消息文件
使用编译好对应语言的类文件进行消息的序列化与反序列化
先来定义一个简单的消息:
message Person {
int32 id = 1;//24
string name = 2;//wujingchao
string email = 3;//
实际的二进制消息为:
08 18 12 0a 77 75 6a 69 6e 67 63 68 61 6f 1a 16 77 75 6a 69 6e 67 63 68 61 6f 39 32 40 67 6d 61 69 6c 2e 63 6f 6d
下面就讲解这段二进制流数据是怎么组成的:
一般情况下int类型都是固定4个字节,protobuf定义了一种变长的int,每个字节最高位表示后面还有没有字节,低7位就为实际的值,并且使用小端的表示方法。例如1,varint的表示方法就为:
是不是这样就省了三个字节。
再例如300,4字节表示为:10 0101100,varint表示为:
所以前面消息为Person的id的值为,即0x18。
负数的最高位为1,如果负数也使用这种方式表示就会出现一个问题,int32总是需要5个字节,int64总是需要10个字节。
所以定义了另外一种类型:sint32,sint64。采用ZigZag编码,所有的负数都使用正数表示,计算方式:
(n && 1) ^ (n && 31)
(n && 1) ^ (n && 63)
Signed Original
Encoded As
使用Varint编码的类型有int32, int64, uint32, uint64, sint32, sint64, bool, enum。Java里面没有对应的无符号类型,int32与uint32一样。
每个消息项前面都会有对应的tag,才能解析对应的数据类型,表示tag的数据类型也是Varint。
tag的计算方式: (field_number && 3) | wire_type
每种数据类型都有对应的wire_type:
Meaning Used For
int32, int64, uint32, uint64, sint32, sint64, bool, enum
fixed64, sfixed64, double
Length-delimited
string, bytes, embedded messages, packed repeated fields
Start group groups (deprecated)
groups (deprecated)
fixed32, sfixed32, float
所以wire_type最多只能支持8种,目前有6种。
所以前面Person的id,field_number为1,wire_type为0,所以对应的tag为
1 &&& 3 | 0
Person的name,field_number为2,wire_type为2,所以对应的tag为
2 &&& 3 | 2 = 0x12
对应Length-delimited的wire type,后面紧跟着的Varint类型表示数据的字节数。
所以name的tag后面紧跟的0x0a表示后面的数据长度为10个字节,即"wujingchao"的UTF-8 编码或者ASCII值:
08 18 12 0a 77 75 6a 69 6e 67 63 68 61 6f 1a 16
嵌套的消息类型embedded messages与packed repeated fields也是使用这种方式表示,对应默认值的数据,是不会写进protobuf消息里面的。
packed repeated与repeated的区别在于编码方式不一样,repeated将多个属性类型与值分开存储。而packed repeated采用Length-delimited方式。下面这个是官方文档的例子:
message Test4 {
repeated int32 d = 4 [packed=true];
// tag (field number 4, wire type 2)
// payload size (6 bytes)
// first element (varint 3)
// second element (varint 270)
// third element (varint 86942)
如果没有packed的属性是这样存储的:
20 //tag(field number 4,wire type 0)
03 //first element (varint 3)
20 //tag(field number 4,wire type 0)
8E 02//second element (varint 270)
20 //tag(field number 4,wire type 0)
// third element (varint 86942)
是不是这种方式比较节省内存,所以proto3的repeated默认就是使用packed这种方式来存储。(proto2与proto3区别在于.proto的语法)。
有了以上的相关概念,我们在读protobuf的源码就比较容易了。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:

我要回帖

更多关于 go protobuf 3.0 的文章

 

随机推荐