protobuf中坑人的2点:
1.oneof类型不能通过json反序列化
2.最里层的message没有null值,都会被赋该类型的默认值
1.oneof类型不能通过json反序列化
定义一个这样的protobuf消息:
message EnvValue {
oneof val {
string s = 1;
double f = 2;
}
}
生成的go语言代码对应的结构为:
type EnvValue struct {
// Types that are valid to be assigned to Val:
// *EnvValue_S
// *EnvValue_F
Val isEnvValue_Val `protobuf_oneof:"val"`
XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
XXX_unrecognized []byte `json:"-" bson:"-"`
XXX_sizecache int32 `json:"-" bson:"-"`
}
定义一个EnvValue对象envValue:
envValue := &pb.EnvValue{
Val: &pb.EnvValue_F{
F: 5,
},
}
使用json.Marshal方法将序列化为json:
{
"val": {
"Val": {
"F": 4
}
}
}
但是当用json.Unmarshal方法将该json反序列化为EnvValue对象,得到的却是如下:
envValue := &pb.EnvValue{
Val: nil,
}
可以看到,protobuf的oneof类型不能通过json反序列化
所以,有通过json反序列化为protobuf的需求时,尽量不要使用oneof类型。
2.最里层的message没有null值,都会被赋该类型的默认值
定义一个protobuf的消息:
message Request {
map<string, Value> env = 1;
}
message Value {
double f = 1;
}
生成的go语言代码对应的结构为:
type Request struct {
Env map[string]*Value `protobuf:"bytes,1,rep,name=env,proto3" json:"env,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-" bson:"-"`
XXX_unrecognized []byte `json:"-" bson:"-"`
XXX_sizecache int32 `json:"-" bson:"-"`
}
构造出对应的json:
{
"env": {
"level": null
},
}
用json.Unmarshal方法将该json反序列化为Request对象,得到如下:
request = &pb.Request{
Env: map[string]*pb.Value{
"level": {
Val: &pb.Value{
F: 0,
},
},
},
}
可以看到,即使赋
最里层
的message为null,protobuf也会给它默认值填充。但是如果赋
“env”: null
,反序列出来的protobuf也为null。
所以,有通过json反序列化为protobuf的需求时,尽量不要赋最里层的message为null
版权声明:本文为a13545564067原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。