为什么google protobuf不支持map的序列化和反序列化?
是因为把线性结构恢复为树状结构的复杂度和直接使用线性结构相同么? ProtoBuf 3.0 pre-release已经支持了:Release Protocol Buffers v3.0.0-alpha-2 · google/protobuf · GitHub 1. protobuf的竞争对手是xml,json等,要支持map的序列化,哪就和json之类没有什么区别
2. protobuf dsl定义各种schema,其实用一个map也能表达,如果再实现map,哪就是自我否定 现在它是支持的。
proto2的文档就已经提到了Maps(Language Guide),但我用protoc2.6编译的时候,map关键字无法通过编译,protoc3.0编译正常,proto举例:
message Person {
required int32 id = 1;
required string name = 2;
optional string email = 3;
map<string, string> values= 4;
} 另外,
官方文档(https://developers.google.com/protocol-buffers/docs/proto#Maps)说了:
The map syntax is equivalent to the following on the wire, so protocol buffers implementations that do not support maps can still handle your data:
message MapFieldEntry {
key_type key = 1;
value_type value = 2;
}
repeated MapFieldEntry map_field = N; protobuf 用二进制序列化的优势,与文本序列化竞争,本质上是一种作弊,但因为它是牛逼公司的牛神发明的,所以它就牛逼大了。因为它牛逼大了,所以只要是它的设计决策,就是正当的 1.支持map就要把key都加入到最终序列化的结果中去,并且效率也会更差(时间空间都损失了),这会削减二进制的优势(跟文本序列化相比),
2.map传输之后,对端一样需要scheme才能解析数据,跟现有方法相比没啥优势,proto文件里的字段相当于是key
3.现有的序列化方法相当于key为整型的嵌套map,利用反射等特性也是能当map用的 3.0里已经支持了,就是还没release 可以曲线救国,用 bson 中转一下:
func mapToPb(in mapinterface{}, pb interface{}) error {
data, err := bson.Marshal(in)
if err != nil {
fmt.Printf(&#34;bson.Marshal(in) failed ,err=%v&#34;, err)
return err
}
if err = bson.Unmarshal(data, pb); err != nil {
fmt.Printf(&#34;bson.Unmarshal(data, pb) failed ,err=%v&#34;, err)
return err
}
return nil
}
pb *ProtoBufStruct := nil
mapToPb(in, &pb) 3.0已经支持了,不过3.0语法变了一些... 虽然现在3.0已经支持,但个人觉得没有必要。使用map必然会用到更多的空间,使用repeat和属性名结合完全可以解决map的需求
页:
[1]
2