
二维数组无法被 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 形式?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号