protoc-生成go指針 protoc-生成go指針

protoc-生成go指針

這裏指的是爲結構體中基礎類型生成go指針,嵌套結構體默認就是指針

爲什麼需要生成指針?

  因爲在一些場景中指針表示的含義是比類型表示的多的

type user struct {
    name    string
    address string
}

假設上述結構體表示一個用戶的信息,創建用戶後希望更新用戶名時該怎麼實現?這裏隱藏的一個問題就是:address爲空字符串時,到底是表示不更新該字段?還是表示將該字段置爲空?

type user struct {
    name    string
    address *string
}

使用指針的意義就是該字段可以額外表示一重含義

  • address字段可以爲空字符串
  • address字段可以爲非空字符串
  • address字段可以直接爲nil,表示該字段無效

proto3生成指針的方法

proto2的結構體字段除了repeated外默認就是指針,不過多說明了

protoclibprotoc 3.17.3

protoc-gen-go1.5.2

optional關鍵字

proto3最開始去掉了optional字段,但是後續又加回來了

syntax = "proto3";

package exp;

option go_package = "./go";


message T {
    optional int32 intPtr = 1;
}
protoc --go_out=./ exp.proto

optional對於protocprotoc-gen-go的版本都是有依賴的,在低版本中還需要帶上額外字段

protoc --experimental_allow_proto3_optional --go_out=./ exp.proto

[需要帶上--experimental_allow_proto3_optional](protocol buffers - How to define an optional field in protobuf 3 - Stack Overflow)

gogo/protobuf

gogo/protobuf是在protobuf基礎上開發出來的一些工具,支持一些擴展語法之類的,使用也是比較廣泛的

使用上面同樣的protoc文件,發現是無法支持的

protoc --gofast_out=./ exp.proto
exp.proto: is a proto3 file that contains optional fields, but code generator protoc-gen-gofast hasn't been updated to support optional fields in proto3. Please ask the owner of this code generator to support proto3 optional.--gofast_out:

gogo/protobuf還未支持optional的語法,一種可行的解法就是在proto3中導入proto2的文件,並且把需要定義爲指針的字段放在proto2

wktpointer擴展語法

syntax = "proto3";

package exp;

import "google/protobuf/wrappers.proto";
import "github.com/gogo/[email protected]/gogoproto/gogo.proto";

option go_package = "./go";


message T {
    google.protobuf.Int32Value intPtr = 1 [(gogoproto.wktpointer) = true];
}
type T struct {
    IntPtr               *int32   `protobuf:"bytes,1,opt,name=intPtr,proto3,wktptr" json:"intPtr,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

不過在網絡上很難找到wktptr的介紹,這個語法也非常讓人困惑

nullable

syntax = "proto3";

package exp;

//import "google/protobuf/wrappers.proto";
import "github.com/gogo/[email protected]/gogoproto/gogo.proto";

option go_package = "./go";


message T {
    int32 intPtr = 1 [(gogoproto.nullable) = false];
}
ERROR: field T.IntPtr is a native type and in proto3 syntax with nullable=false there exists conflicting implementations when encoding zero values--gofast_out: protoc-gen-gofast: Plugin failed with status code 1.

nullable擴展字段無法支持原生類型,此擴展字段對此是無效的

  

embed

最簡單的方法就是通過import的方式在proto3中加載proto2的語法,但是實際上通過內嵌結構體的方式來優化一下

message T {
    S s = 1 [(gogoproto.embed)=true];
}

這樣可以將需要定義爲指針的元素定義到proto2中然後內嵌進來

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章