英文:
Is there a simple way to decode different objects in an array of json by golang?
问题
一个 JSON 流描述了一个形状数组。这些形状可以是三角形、矩形或正方形。
例如:
{"shapes": [
{"type": "triangle", "side1": 3, "side2": 4, "side3": 5},
{"type": "rectangle", "width": 4, "height": 3},
{"type": "square", "side": 3}
]}
这些结构在我的 Golang 代码中声明如下:
type Shape struct {
Type string `json:"type"`
}
type Triangle struct {
Shape
Side1 int `json:"side1"`
Side2 int `json:"side2"`
Side3 int `json:"side3"`
}
type Rectangle struct {
Shape
Width int `json:"width"`
Height int `json:"height"`
}
type Square struct {
Shape
Side int `json:"side"`
}
我该如何将 JSON 解码为对象切片?非常感谢。
英文:
A json stream described an array of shapes. The shapes mayb be triangles, rectangles or squares.
For example:
{"shapes": [
{"type": "triangle", "side1": 3, "side2": 4, "side3": 5},
{"type": "rectangle", "width": 4, "height": 3},
{"type": "square", "side": 3}
]}
These structures are declared in my golang code:
type Shape struct {
Type string `json:"type"`
}
type Triangle struct {
Shape
Side1 int `json:"side1"`
Side2 int `json:"side2"`
Side3 int `json:"side3"`
}
type Rectangle struct {
Shape
Width int `json:"width"`
Height int `json:"height"`
}
type Square struct {
Shape
Side int `json:"side"`
}
How can I decode the json into an object slice? Thank you very much.
答案1
得分: 1
创建一个新的类型Shapes
来解析shapes
,并实现自定义的UnmarshalJSON
方法来解析Shapes
。
type Shapes struct {
Shapes []interface{} `json:"shapes"`
}
func (b *Shapes) UnmarshalJSON(data []byte) error {
var v = struct {
Shapes []map[string]interface{} `json:"shapes"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
types := make([]interface{}, 0)
for _, shape := range v.Shapes {
shp := Shape{Type: shape["type"].(string)}
switch shp.Type {
case "triangle":
typ := Triangle{
Shape: shp,
Side1: int(shape["side1"].(float64)),
Side2: int(shape["side2"].(float64)),
Side3: int(shape["side3"].(float64)),
}
types = append(types, typ)
case "rectangle":
typ := Rectangle{
Shape: shp,
Width: int(shape["width"].(float64)),
Height: int(shape["height"].(float64)),
}
types = append(types, typ)
case "square":
typ := Square{
Shape: shp,
Side: int(shape["side"].(float64)),
}
types = append(types, typ)
}
}
b.Shapes = types
return nil
}
将json字符串解析为Shapes
类型。你可以在Shapes.Shapes
数组中访问你的形状类型。
func main() {
jStr := `{"shapes": [
{"type": "triangle", "side1": 3, "side2": 4, "side3": 5},
{"type": "rectangle", "width": 4, "height": 3},
{"type": "square", "side": 3}
]}`
shapes := Shapes{}
err := json.Unmarshal([]byte(jStr), &shapes)
if err != nil {
panic(err)
}
fmt.Println(shapes)
}
完整代码请参考这里
英文:
Create new type Shapes
to unmarshal shapes
and implement your custom UnmarshalJSON
to Shapes
type Shapes struct {
Shapes []interface{} `json:"shapes"`
}
func (b *Shapes) UnmarshalJSON(data []byte) error {
var v = struct {
Shapes []map[string]interface{} `json:"shapes"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
types := make([]interface{}, 0)
for _, shape := range v.Shapes {
shp := Shape{Type: shape[`type`].(string)}
switch shp.Typ() {
case `triangle`:
typ := Triangle{
Shape:shp,
Side1: int(shape[`side1`].(float64)),
Side2: int(shape[`side2`].(float64)),
Side3: int(shape[`side3`].(float64)),
}
types = append(types, typ)
case `rectangle`:
typ := Rectangle{
Shape: shp,
Width: int(shape[`width`].(float64)),
Height: int(shape[`height`].(float64)),
}
types = append(types, typ)
case `square`:
typ := Square{
Shape: shp,
Side: int(shape[`side`].(float64)),
}
types = append(types, typ)
}
}
b.Shapes = types
return nil
}
Unmarshal json string to Shapes
type. You can access your shape types in Shapes.Shapes array.
func main() {
jStr := `{"shapes": [
{"type": "triangle", "side1": 3, "side2": 4, "side3": 5},
{"type": "rectangle", "width": 4, "height": 3},
{"type": "square", "side": 3}
]}`
shapes := Shapes{}
err := json.Unmarshal([]byte(jStr), &shapes)
if err != nil {
panic(err)
}
fmt.Println(shapes)
}
Find full code here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论