2 回答
TA贡献1860条经验 获得超9个赞
您可以将 JSON 解组为一片地图,然后从该片中提取您需要的任何内容:
package main
import (
"encoding/json"
"fmt"
"log"
)
type Entry struct {
Animalname string `json:"animal_name"`
Location string
}
func main() {
data := []byte(`[{"animal_name": "Goofy", "location": "Europe"}, {"person_name": "Gigo", "location": "Asia"}]`)
// json.Unmarshal will initialize it as a slice of maps: []map[string]string.
// Alternatively, you can set the type explicitly:
// var entries []map[string]string
var entries interface{}
err := json.Unmarshal(data, &entries)
if err != nil {
log.Fatal(err)
}
fmt.Println(entries)
}
TA贡献1877条经验 获得超1个赞
您可以json.Unmarshaler
在一片接口上实现该接口。然后在这个自定义函数中使用一些逻辑来确定应该使用哪种结构类型。在我们知道要使用哪种类型之前,我曾经json.RawMessage
避免完全解组数据。
package main
import (
"encoding/json"
"strings"
"github.com/davecgh/go-spew/spew"
)
type EntitySlice []Entity
func (es *EntitySlice) UnmarshalJSON(bytes []byte) error {
var objSlice []json.RawMessage
err := json.Unmarshal(bytes, &objSlice)
if err != nil {
return err
}
for _, obj := range objSlice {
kv := make(map[string]json.RawMessage)
err = json.Unmarshal(obj, &kv)
if err != nil {
return err
}
var entityType string
for k := range kv {
i := strings.Index(k, "_name")
if i != -1 {
entityType = k[:i]
break
}
}
var e Entity
switch entityType {
case "person":
e = &Person{}
case "animal":
e = &Animal{}
}
err = json.Unmarshal(obj, &e)
if err != nil {
return err
}
*es = append(*es, e)
}
return nil
}
type Entity interface {
EntityMarker()
}
type Person struct {
Name string `json:"person_name"`
Location string
}
// Just so we implement Entity
func (p *Person) EntityMarker() {}
type Animal struct {
Name string `json:"animal_name"`
Location string
}
// Just so we implement Entity
func (a *Animal) EntityMarker() {}
func main() {
data := []byte(`[{"animal_name": "Goofy", "location": "Europe"}, {"person_name": "Gigo", "location": "Asia"}]`)
var entitySlice EntitySlice
err := json.Unmarshal(data, &entitySlice)
if err != nil {
spew.Dump(err)
}
spew.Dump(entitySlice)
}
- 2 回答
- 0 关注
- 93 浏览
添加回答
举报