博客 / 詳情

返回

protobuf-2 消息類型

基本數據類型

syntax = "proto3";

// 所有基本數據類型
// protoc --go_out=. scalar.proto
option go_package = "../service";

message scalar{
  double filed1 = 1;  //float64
  float field2 = 2;   //float32
  int32 field3 = 3;   //int32
  int64 field4 = 4;   //int64
  uint32 field5 = 5;  //uint32
  uint64 field6 = 6;  //uint64
  sint32 field7 = 7;  //int32
  sint64 field8 = 8;  //int64
  fixed32 field9 = 9; //uint32
  fixed64 field10 = 10; //uint64
  sfixed32 field11 = 11; //int32
  sfixed64 field12 = 12; //int64
  bool field13 = 13;  //bool
  string  field14 = 14; //string
  bytes field15 = 15;  //[]byte
}

生成的go代碼
image.png

枚舉類型

syntax = "proto3";

// protoc --go_out=. enumerations.proto
option go_package = "../service";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }
  Corpus corpus = 4;
}

生成的go代碼

image.png

image.png

其他消息類型

syntax = "proto3";

// protoc --go_out=. other_message_type.proto
option go_package = "../service";

message SearchResponse {
  repeated Result results = 1;
}

message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}

如果使用的類型定義在其他proto文件中,需要import導入

image.png

image.png

嵌套類型

syntax = "proto3";

// protoc --go_out=. nested.proto
option go_package = "../service";

message NestedSearchResponse {
  message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
  }
  repeated Result results = 1;
}

image.png

image.png

更新消息類型

有時候你不得不修改正在使用的proto文件,比如為類型增加一個字段,protobuf支持這種修改而不影響已有的服務,不過你需要遵循一定的規則:

  • 不要改變已有字段的字段編號
  • 當你增加一個新的字段的時候,老系統序列化後的數據依然可以被你的新的格式所解析,只不過你需要處理新加字段的缺省值。 老系統也能解析你信息的值,新加字段只不過被丟棄了
  • 字段也可以被移除,但是建議你Reserved這個字段,避免將來會使用這個字段
  • int32, uint32, int64, uint64 和 bool類型都是兼容的
  • sint32 和 sint64兼容,但是不和其它整數類型兼容
  • string 和 bytes兼容,如果 bytes 是合法的UTF-8 bytes的話
  • 嵌入類型和bytes兼容,如果bytes包含一個消息的編碼版本的話
  • fixed32和sfixed32, fixed64和sfixed64
  • enum和int32, uint32, int64, uint64格式兼容
  • 把單一一個值改變成一個新的oneof類型的一個成員是安全和二進制兼容的。把一組字段變成一個新的oneof字段也是安全的,如果你確保這一組字段最多隻會設置一個。把一個字段移動到一個已存在的oneof字段是不安全的

常見問題

1.protoc-gen-go: unable to determine Go import path for xxx

image.png

在新版中,必須指定 go_package

// 通過分號分割
// 前半部分是path 表示生成文件的存放目錄
// 後半部分是生成go文件的包名
option go_package="example.com/protos/foo;package_name";

具體參考這裏 https://github.com/golang/pro...

參考

  • https://developers.google.com...
  • https://colobu.com/2019/10/03...
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.