青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 298  文章 - 377  trackbacks - 0
<2018年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用鏈接

留言簿(34)

隨筆分類

隨筆檔案

文章檔案

相冊

收藏夾

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

讀完protobuf一些文檔,寫點東西,權作記憶。

https://github.com/google/protobuf/blob/master/CHANGES.txt

google發布了protobuf v3,為了pb更好用,更跨語言,他對protobuf v2做了以下change:

      1. Removal of field presence logic for primitive value fields(匪夷所思,留存以待以后翻譯出來), 刪除required(大大地贊同,即保留repeated,required和optional都不要了,默認就是optional),刪除默認值(不明白)。谷歌生成這些改變視為了更好的兼容Android Java、Objective C和Go語言;

      2. 刪除對unknown field的支持;

      3. 不再支持繼承,以Any type代之;

      4 修正了enum中的unknown類型;

      5 支持map;

         protobuf v2和v3都支持map了,其聲明形式如下: 

         message Foo {

                map<string, string> values = 1;

         }

         注意,此處的map是unordered_map。

      6 添加了一些類型集,以支持表述時間、動態數據等;

      7 默認以json形式代替二進制進行編碼。

目前v3 alpha版僅僅實現了1-5這五個feature,6和7還未支持。新添加了syntax關鍵字,以指明proto文件的protobuf協議版本,不指明則是v2。如:

 // foo.proto

      syntax = "proto3";

      message Bar {...}

如果你目前使用了v2,那么暫時不支持你切換到v3,我們還會對v2提供支持。如果你是新手,那就大膽使用v3吧。



https://github.com/golang/protobuf

1 go的protobuf實現不支持RPC。

2 go的protobuf實現了一個go的插件protoc-gen-go,他放置的地方必須在$GOBIN里面,默認放在$GOPATH/bin。它也必須在$PATH里面,以讓protoc編譯器找到。protoc把proto文件編譯成go的源碼文件,其名稱后綴是.pb.go,protoc命令格式如下:

protoc --go_out=. *.proto

3 .pb.go源碼的一些事項如下:

  - 變量名稱采用駱駝命名法,如camel_case被編譯為CamelCase.

  - 不會為field生成set方法,直接為成員賦值即可。 

  - 沒有setter,但是有getter方法,如果field被設置了值,則返回設置的值。如果沒有設置,則返回默認值。如果連message都沒有收到,就返回nil。

  - struct的所有成員初始值都是零值,如果要給其成員賦值,就必須在序列化之前。序列化后再修改struct的成員值,沒有任何意義。

  - struc的 Reset()會將struct的所有field的值清零。

  - 非repeated的field成員的類型都是指針類型,當它為空時,意味著其值為空。如"required field int32 f "或者"optional field int32 f "被編譯后的類型都是F *int32。

  - Repeated類型的fields被編譯后則是slices.

  - 與其他語言一樣,go會生成Helper函數,以便于設置field的值。針對獲取值得Helper函數不再建議使用。                        msg.Foo = proto.String("hello") // set field

  - 一個field如果有default值,則這個值會被編譯為一個常量,其名稱的規則為Default_StructName_FieldName,而且相關的Get方法會默認返回這個值。不見直接用這些const值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
message Test {
    optional int32 type = 2 [default=77];
    extensions 100 to 199;
}
 
type Test struct {
    Type             *int32                    `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
}
 
 
const Default_Test_Type int32 = 77
     
func (m *Test) GetType() int32 {
    if m != nil && m.Type != nil {
        return *m.Type
    }
    return Default_Test_Type
}


  -  Enum類型會對類型名稱和其值分別處理,其值的Enum名稱以類型做前綴,每個field的名稱和值會形成map,可以互相查找。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
enum FOO {
    X = 17; 
    Y = 18; 
};
==>
type FOO int32
 
const (
    FOO_X FOO = 17
    FOO_Y FOO = 18
)
 
var FOO_name = map[int32]string{
    17: "X",
    18: "Y",
}
var FOO_value = map[string]int32{
    "X": 17, 
    "Y": 18, 
}
 
func (x FOO) Enum() *FOO {
    p := new(FOO)
    *p = x 
    return p
}
func (x FOO) String() string {
    return proto.EnumName(FOO_name, int32(x))
}
func (x *FOO) UnmarshalJSON(data []byte) error {
    value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO")
    if err != nil {
        return err
    }
    *x = FOO(value)
    return nil
}

  - 如果group和enum是內置在message中的,則其名稱的前綴會有message的名稱。 

  - Extensions會被編譯為一個變量,其名稱開頭為E_。extension相關的方法有 HasExtension, ClearExtension, GetExtension, SetExtension .

  - 序列化方法有Marshal和Unmarshal.





https://developers.google.com/protocol-buffers/docs/proto:

1 default value。bool的默認值是false,數值的默認值是0,enum的默認值是其第一個元素,string的默認值是空字符串。

 2 tag id. id 1-15占用1個字節,16到2047占用兩個字節。所以1-15要留個頻繁使用的字段,不要剛開始定義字段的是時候都分配出去。

   tag值最小是1, 最大是(2^29 - 1)即536,870,911,但是要避開19000到19999,這是protobuf內置的類型要用到的tag id。 

 3 enum可以有alias。enum的值不能為負數。

 enum EnumAllowingAlias {

  option allow_alias = true;

  UNKNOWN = 0;

  STARTED = 1;

  RUNNING = 1;

}

enum EnumNotAllowingAlias {

  UNKNOWN = 0;

  STARTED = 1;

  // RUNNING = 1;  // Uncommenting this line will cause a compile error inside Google and a warning message outside.

}

 4 當協議更新的時候,如果某個字段過時了,就可以更改field的name,如"OBSOLETE_xxx",以告訴使用者不要在使用這個field。

   也可以更改field type,前提是tag id不變,這些類型就是兼容的(之所以能兼容,按照我的理解,一個field就是一個kay-value對,tag id為key,value即為值,而type只是在序列化和反序列化的時候起到解釋值的作用,并無其他作用;key = (tag << 3) | wire_type,即類型占用最多3個字節,所以有上面的tag范圍是2^29 - 1)。如下幾個類型是兼容的:

   A int32 uint32 int64 uint64 bool    

   B sint32 siint64

   C string bytes (字符類型是UTF8)

   D fixed32 sfixed32 fixed64 sfixed64

   E optional repeated

   F default([default = value])value也可以被修改

 5 protoc --proto-path= --cpp_out= --java_out= file.proto

   --proto-path可以被-I代替。

 6 protobuf對repeated壓縮不夠好,所以盡量在后面加上[packed = true]。

 7 序列化的時候不能把多個message序列化后的內容放在一起發出去,盡量以len1 + msg1 + len2 + msg2這種形式發送。

 8 不要讓protobuf對象成為全局變量或者類成員,因為其clear方法只會把占用的內存空間清零,而不會釋放,使得進程空間越來越大,可參考《Protobuf使用不當導致的程序內存上漲問題》。 



https://developers.google.com/protocol-buffers/docs/encoding:

1 正常field的kv對的編碼順序是:1 小端序;2 varints,即每7個bit為一個byte,在byte的第一個bit賦值1,最后一個byte的第一個bit賦值0;3 對field的tag加type構成key,值為value,即((tag_id << 3) | wire_type) + value。但是針對repeated這種,其結果為((tag_id << 3) | wire_type) + len + value,長度len為array size,prootbuf解析度時候,會根據wire_type為2知道這是個array。


2 如果序列化的時候,多個kv對用了一個tag id,則這個kv對應的field的值為最后一次出現的kv對的值。

3 repeated的[packed = true]只有type為數值的時候才能用。


https://github.com/google/protobuf/tree/v3.0.0-alpha-1

1 安裝步驟:

  

$ ./configure --prefix=/home/user/bin/ $ make $ make check $ make install


2 如果不想生成動態protobuf庫,則用命令./configure --disable-shared。

posted on 2018-01-06 18:09 聶文龍 閱讀(9257) 評論(0)  編輯 收藏 引用
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩亚洲一区二区| 午夜精品久久久久久久久| 99视频精品全部免费在线| 在线精品高清中文字幕| 亚洲国产另类久久精品| 亚洲国产精品视频一区| 亚洲日本一区二区| 99精品久久免费看蜜臀剧情介绍| 一本大道久久a久久精品综合 | 99热这里只有成人精品国产| 日韩午夜av电影| 亚洲欧美日韩精品久久久久| 久久久久久久久岛国免费| 免费一区二区三区| 欧美日韩亚洲一区三区| 国产精品久久看| 亚洲成人直播| 亚洲午夜久久久久久尤物| 久久久久欧美精品| 亚洲精品欧美精品| 午夜精品美女自拍福到在线| 久久久免费精品视频| 欧美日韩国产成人| 国产在线拍偷自揄拍精品| 日韩图片一区| 欧美天天在线| 狠狠色综合网站久久久久久久| 亚洲乱码久久| 久久久久成人精品| 99在线精品视频在线观看| 久久婷婷国产麻豆91天堂| 国产精品女主播在线观看| 亚洲电影在线播放| 久久精品国产免费观看| 亚洲精品国产精品国自产观看浪潮| 亚洲欧美激情在线视频| 欧美精品一区二区三区四区| 一区二区三区无毛| 久久不射中文字幕| 亚洲天堂成人在线观看| 欧美日韩激情小视频| 日韩视频免费观看| 久久婷婷丁香| 欧美啪啪一区| 在线播放视频一区| 久久福利毛片| 亚洲免费影视| 国产精品mv在线观看| 亚洲精品久久久久久一区二区| 性色av一区二区三区红粉影视| 亚洲日本理论电影| 欧美jizzhd精品欧美喷水 | 亚洲乱码国产乱码精品精天堂 | 亚洲国产综合在线| 女女同性精品视频| 久久久久久久久久久久久久一区| 国产欧美日韩三级| 欧美在线网址| 欧美亚洲在线观看| 国产在线观看精品一区二区三区| 欧美一区在线看| 欧美一级在线亚洲天堂| 国产欧美日韩不卡免费| 久久国产主播| 久久精品午夜| 亚洲高清av| 亚洲欧洲久久| 欧美日韩亚洲精品内裤| 亚洲伊人久久综合| 篠田优中文在线播放第一区| 国产一区视频在线观看免费| 久久久久99| 鲁大师成人一区二区三区| 亚洲黄一区二区三区| 亚洲国产一区二区三区a毛片| 欧美国产日本| 亚洲男女自偷自拍| 欧美一区二区成人6969| 精品999久久久| 亚洲高清久久久| 欧美精品在线观看91| 亚洲视频免费看| 欧美在线短视频| 亚洲另类在线一区| 亚洲欧美bt| 亚洲精品在线观看视频| 亚洲一区二区三区乱码aⅴ| 国产在线精品成人一区二区三区| 欧美激情第4页| 国产精品a久久久久久| 久久久久88色偷偷免费| 欧美猛交免费看| 久久久精品久久久久| 欧美激情网友自拍| 久久精品中文字幕免费mv| 午夜久久久久久| 国产精品国产三级国产专区53| 欧美一区91| 欧美成人一区二区三区片免费| 亚洲一二三区在线| 久久精品欧洲| 亚洲视频axxx| 久久亚洲午夜电影| 香蕉av777xxx色综合一区| 免费不卡中文字幕视频| 欧美一级在线视频| 欧美日韩大陆在线| 欧美成人国产| 国产综合视频在线观看| 一区二区三区视频观看| 亚洲精品女av网站| 久久久久久久久一区二区| 亚洲男人的天堂在线| 免费人成网站在线观看欧美高清| 欧美亚洲日本国产| 欧美色欧美亚洲另类二区| 欧美黑人在线播放| 韩国精品主播一区二区在线观看| 宅男噜噜噜66国产日韩在线观看| 亚洲破处大片| 麻豆精品精华液| 免费看av成人| 一区二区三区自拍| 欧美在线电影| 久久精品国产欧美激情| 国产精品www.| 日韩亚洲欧美成人| 一区二区三区av| 欧美精品一卡| 亚洲欧洲视频| 日韩亚洲欧美一区| 欧美高清hd18日本| 亚洲国产精品久久久| 亚洲精品一区二区三区四区高清| 久久综合狠狠综合久久综青草| 久久精品久久99精品久久| 国产婷婷色一区二区三区在线| 亚洲免费视频成人| 久久久91精品国产一区二区三区 | 一本色道久久综合亚洲精品不卡| 蜜桃久久av| 亚洲国产99| 一区二区精品| 国产精品国产成人国产三级| 亚洲午夜av在线| 欧美中文字幕久久| 经典三级久久| 欧美成人综合| 夜夜嗨av一区二区三区四区 | 欧美二区在线播放| 亚洲人成网在线播放| 这里只有精品视频| 国产免费观看久久黄| 久久久国产精彩视频美女艺术照福利| 久久久久国产精品一区| 在线日韩av| 亚洲精品婷婷| 久久精品在这里| 国产免费成人在线视频| 午夜精品免费在线| 欧美成人精品1314www| 亚洲国产欧美一区二区三区同亚洲 | 久久亚洲精品欧美| 亚洲激情欧美| 欧美一区二区视频观看视频| 激情丁香综合| 欧美日韩国产电影| 亚洲欧美清纯在线制服| 美女亚洲精品| 亚洲一品av免费观看| 一区二区三区在线视频免费观看| 欧美激情性爽国产精品17p| 亚洲午夜精品久久| 欧美激情二区三区| 欧美在线亚洲综合一区| 亚洲人精品午夜在线观看| 国产精品日产欧美久久久久| 久久久精品免费视频| 在线性视频日韩欧美| 免费在线观看成人av| 亚洲欧美伊人| 亚洲美女电影在线| 黄色成人在线网站| 国产精品久久久久一区二区| 欧美成人一区二区三区| 久久久99爱| 亚洲一区亚洲| 9久草视频在线视频精品| 欧美gay视频激情| 午夜亚洲伦理| 亚洲午夜久久久久久久久电影院| 亚洲国产另类久久精品| 国内精品视频一区| 国产精品网站在线播放| 欧美日韩一区二区三区在线| 欧美成人在线影院| 免费观看日韩av| 久久香蕉国产线看观看网| 午夜电影亚洲| 亚洲综合日本|