【发布时间】:2017-07-02 13:33:14
【问题描述】:
在此示例中,我将尝试加载包含多边形的 2D 场景。在代码中,我会有许多不同的结构,例如圆形、方形、矩形、五边形等。 所有人都将共享共同的功能,例如面积和周长。 场景本身将存储为 Polygon 界面的切片。
这是我用来测试的代码:
package main
import (
"encoding/json"
"fmt"
"math"
)
type Polygon interface {
Area() float32
}
type Rectangle struct {
Base float32 `json:"base"`
Height float32 `json:"height"`
X float32 `json:"x"`
Y float32 `json:"y"`
}
func (r *Rectangle) Area() float32 {
return r.Base * r.Height
}
type Circle struct {
Radius float32 `json:"radius"`
X float32 `json:"x"`
Y float32 `json:"y"`
}
func (c *Circle) Area() float32 {
return c.Radius * c.Radius * math.Pi
}
func main() {
rect := Rectangle{Base: 10, Height: 10, X: 10, Y: 10}
circ := Circle{Radius: 10, X: 0, Y: 0}
sliceOfPolygons := make([]Polygon, 0, 2)
sliceOfPolygons = append(sliceOfPolygons, &rect, &circ)
jsonData, err := json.Marshal(sliceOfPolygons)
if err != nil {
panic(err)
}
fmt.Println(string(jsonData))
newSlice := make([]Polygon, 0)
err = json.Unmarshal(jsonData, &newSlice)
if err != nil {
panic(err)
}
}
在此示例中,我设置了一个由 2 个多边形组成的切片,对其进行编组,然后再次尝试对其进行解组。 编组后的字符串是:
[{"base":10,"height":10,"x":10,"y":10},{"radius":10,"x":0,"y":0}]
但是当我尝试Unmarshal 时它会恐慌:
panic: json: cannot unmarshal object into Go value of type main.Polygon
如果这可行,它将非常有用且易于使用。我会说Unmarshall 无法从json字符串中区分Rectangle 和Circle,因此它不可能知道要构建什么结构。
有没有办法标记结构或告诉Unmarshal如何区分这个结构?
【问题讨论】:
-
Polygon是一个接口,你不能将interface传递给解组器。您必须传递 具体 类型。 快速 解决方案是将其解组为[]map[string]interface{},但随后您需要将其转换 以手动构造。如果允许更改数据结构,请使用json.RawMessageto delay parsing part of your JSON
标签: json go struct interface unmarshalling