2

我正在尝试将一些 json 数据解组为原始消息。

JSON

   {
        "id": 1,
        "first_name": "name",
        "phone_numbers": []
    }

原型

message Item {
  uint32 id=1;
  string name=2;
  repeated string numbers=3;
}

原型.go

type Item struct {
    Id    uint32   `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
    Name   string   `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
    Numbers   []string `protobuf:"bytes,4,rep,name=numbers" json:"numbers,omitempty"`
}

如何将上述 JSON 映射到我的原型消息(据我所知,无法在原型 atm 中指定标签)?

4

1 回答 1

0

您的 JSON 文档与原型定义不匹配;name != first_name 和 numbers != phone_numbers。

您可以定义另一种与 Item 具有相同字段但结构标记不同的类型,然后转换为 Item:

    var x struct {
            Id      uint32   `json:"id,omitempty"`
            Name    string   `json:"first_name,omitempty"`
            Numbers []string `json:"phone_numbers,omitempty"`
    }

    if err := json.Unmarshal(jsonDoc, &x); err != nil {
            log.Fatal(err)
    }

    var i = Item(x)

如果您要解码的每个JSON 文档都有这种结构,让 Item 实现json.Unmarshaler可能会更方便:

package main

import (
        "encoding/json"
        "fmt"
        "log"
)

var jsonDoc = []byte(`
{
  "id": 1,
  "first_name": "name",
  "phone_numbers": [
    "555"
  ]
}
`)

type Item struct {
        Id      uint32   `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
        Name    string   `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
        Numbers []string `protobuf:"bytes,4,rep,name=numbers" json:"numbers,omitempty"`
}

// You can define this function is item_json.go or so, then it 
// isn't removed if you re-generate your types.
func (i *Item) UnmarshalJSON(b []byte) error {
        type item struct {
                Id      uint32   `json:"id,omitempty"`
                Name    string   `json:"first_name,omitempty"`
                Numbers []string `json:"phone_numbers,omitempty"`
        }

        var x item
        if err := json.Unmarshal(jsonDoc, &x); err != nil {
                return err
        }

        *i = Item(x)

        return nil
}

func main() {
        var i Item
        if err := json.Unmarshal(jsonDoc, &i); err != nil {
                log.Fatal(err)
        }

        fmt.Printf("%#v\n", i)
}

在操场上试试:https: //play.golang.org/p/0qibavRJbwi

于 2018-04-05T15:37:53.740 回答