如何用 proto3 处理二维数组并将其转换为 map 形式?

如何用 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 形式?的详细内容,更多请关注硕下网其它相关文章!