Language Guideに以下のようにフィールドに値がセットされていない場合はdefault valueが使われることが書かれています。
When a message is parsed, if the encoded message does not contain a particular singular element, the corresponding field in the parsed object is set to the default value for that field.
ということは何も書かれていない(0 byteの)バリナリをパースしようとすると、すべてのフィールドがdefault valueとなるはずなので試してみました。
パースする.proto
以下のような.proto
を用意します。
syntax = "proto3"; package blank; message User { int32 id = 1; string name = 2; fixed64 age = 3; Contact contact = 4; } message Contact { string phone = 1; string email = 2; }
protocします。
❯ protoc -I=blank/ --go_out=blank/ blank.proto
パースする
0 byteの入力としてin := []byte{}
を使います。
in
をUser
にパースし、各フィールドを標準出力して、default valueになっているか確認します。
package main import ( "fmt" "log" pb "github.com/cipepser/protobuf-sample/blank" "github.com/golang/protobuf/proto" ) func main() { user := &pb.User{} in := []byte{} if err := proto.Unmarshal(in, user); err != nil { log.Fatal(err) } fmt.Println("ID: ", user.Id) fmt.Println("Name: ", user.Name) fmt.Println("Age: ", user.Age) fmt.Println("Contact: ", user.Contact) }
結果
実行結果は以下の通りです。
❯ go run BlankRead.go ID: 0 Name: Age: 0 Contact: <nil>
ちゃんとdefault valueでパースできました。
ちなみに、上記の通りuser.Contact
はnil
がdefault valueのため、Phone
やEmail
にアクセスしようとするとpanicになります。
fmt.Println("Phone: ", user.Contact.Phone) // panic: runtime error: invalid memory address or nil pointer dereference