【问题标题】:json: cannot unmarshal object into Go value of type Auction.Itemjson:无法将对象解组为 Auction.Item 类型的 Go 值
【发布时间】:2017-01-06 23:46:54
【问题描述】:

我在反序列化我的对象时遇到问题。我使用该对象的接口来调用序列化,并且通过读取输出,序列化工作完美。这是我的对象的底层结构:

type pimp struct {
    Price       int
    ExpDate     int64
    BidItem     Item
    CurrentBid  int
    PrevBidders []string
}

这是它实现的接口:

type Pimp interface {
    GetStartingPrice() int
    GetTimeLeft() int64
    GetItem() Item
    GetCurrentBid() int
    SetCurrentBid(int)
    GetPrevBidders() []string
    AddBidder(string) error
    Serialize() ([]byte, error)
}

Serialize() 方法:

func (p *pimp) Serialize() ([]byte, error) {
    return json.Marshal(*p)
}

您可能已经注意到,pimp 有一个名为 Item 的变量。这也是一个接口:

type item struct {
    Name string
}

type Item interface {
    GetName() string
}

现在序列化此类对象的样本会返回以下 JSON:

{"Price":100,"ExpDate":1472571329,"BidItem":{"Name":"ExampleItem"},"CurrentBid":100,"PrevBidders":[]}

这是我的反序列化代码:

func PimpFromJSON(content []byte) (Pimp, error) {
    p := new(pimp)
    err := json.Unmarshal(content, p)
    return p, err
}

但是,运行它会给我以下错误:

json: cannot unmarshal object into Go value of type Auction.Item

感谢任何帮助。

【问题讨论】:

  • 你不能解组为空接口,因为 json 包无法知道在该接口中使用什么具体类型。
  • 有没有办法告诉它是什么类型的?有点像json:"varName"?
  • 不,因为类型不能被名称引用(如果你不直接使用类型,它甚至可能不在你编译的二进制文件中)。最好尽量不要解组到接口中(除了使用interface{}作为json包默认类型)。

标签: json serialization go


【解决方案1】:

解组器不知道用于 nil BidItem 字段的具体类型。您可以通过将字段设置为适当类型的值来解决此问题:

func PimpFromJSON(content []byte) (Pimp, error) {
    p := new(pimp)
    p.BidItem = &item{}
    err := json.Unmarshal(content, p)
    return p, err
}

playground example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-05
    • 2021-05-20
    • 2018-05-06
    • 1970-01-01
    • 2018-05-23
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多