如何用 proto3 处理二维数组并将其转换为 map 形式?
二维数组无法被 proto3 转换为 map 形式
在示例中,将 json 数据转换为 proto3 消息时,有一个二维数组 "column"。然而,当你生成 go 代码后发现生成了一个嵌套的结构,其中包含一个额外的 "innerarray" 字段。这导致 viper 解析时出现错误,因为它期望一个 map 类型的 "column" 字段。
问题所在:
proto3 不支持多维数组。
解决方案:
如果必须保留二维数组的结构,则无法直接使用 proto3 进行消息定义。你可以使用 proto3 的 well-known types,通过 value、listvalue 和 struct 提供对任意 json 的支持。
通过以下方式实现:
proto 文件:
message tool_bar { message tool_item { string name = 1; string role = 2; } value column = 1; // 使用 value 代替 array2d repeated value row = 2; // 使用 value 代替 array2d }
生成的 go 代码:
type configreply_toolbar struct { column []*configvalue `protobuf:"bytes,1,rep,name=column,proto3" json:"column,omitempty"` row []*configvalue `protobuf:"bytes,2,rep,name=row,proto3" json:"row,omitempty"` }
使用 value 类型后,你可以将二维数组编码为嵌套的 listvalue,但在 proto 文件中无法指定其嵌套结构的具体细节。你需要手动处理 json 数据并将其转换为适当的格式。
viper 解析:
使用 viper 解析具有嵌套结构的 json 时,需要使用 unmarshallkey 方法。
func HandleViper() error { viper.SetConfigType("json") err := viper.ReadConfig(strings.NewReader(jsonStr)) if err != nil { return err } t := &ConfigReply_ToolBar{} if err := viper.UnmarshalKey("toolbar.column", t.Column); err != nil { return err } if err := viper.UnmarshalKey("toolbar.row", t.Row); err != nil { return err } return nil }
缺点:
使用 value 类型的缺点是,你失去了在 proto 文件中定义消息结构的优势。你需要手动处理 json 数据的结构,并在代码中验证其有效性。
以上就是如何用 proto3 处理二维数组并将其转换为 map 形式?的详细内容,更多请关注硕下网其它相关文章!