我正在尝试动态设置interface {}类型的字段。在下面的所有情况下,json解组成正确的结构,但在"问题"如果json unmarshals to [] interface {}。对于那种情况,我期待[]人。为什么我的#34;问题"?
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type Employees struct {
Indicator string `json:"indicator"`
Items interface{} `json:"items"`
}
type Person struct {
Name string `json:"name"`
}
func main() {
simple()
easy()
moreDifficult()
problem()
}
var j = []byte(`{"name": "bob"}`)
var jj = []byte(`[{"name": "bob"}, {"name": "jim"}, {"name": "fred"}]`)
func simple() {
p := Person{}
if err := json.Unmarshal(j, &p); err != nil {
fmt.Println(err)
}
fmt.Println("easy:", p, reflect.TypeOf(p))
}
func easy() {
p := []Person{}
if err := json.Unmarshal(jj, &p); err != nil {
fmt.Println(err)
}
fmt.Println("easy:", p, reflect.TypeOf(p))
}
func moreDifficult() {
var j = []byte(`{"indicator": "more difficult"}`)
e := Employees{}
if err := json.Unmarshal(j, &e); err != nil {
fmt.Println(err)
}
fmt.Println("moreDifficult", e.Items, reflect.TypeOf(e.Items))
}
func problem() {
var j = []byte(`{"indicator:": "problem"}`)
e := Employees{}
if err := json.Unmarshal(j, &e); err != nil {
fmt.Println(err)
}
fmt.Println("problem:", e.Items, reflect.TypeOf(e.Items)) // why not []Person???
}
func (e *Employees) UnmarshalJSON(b []byte) error {
type alias Employees
a := &alias{}
if err := json.Unmarshal(b, &a); err != nil {
return err
}
e.Indicator = a.Indicator
var k = jj
if e.Indicator == "more difficult" {
k = j
e.Items = &Person{}
} else {
e.Items = []Person{}
}
return json.Unmarshal(k, &e.Items)
}
答案 0 :(得分:1)
问题是接口的基础值不是指针:
e.Items = []Person{}
虽然您确实传递了指向接口本身的指针:
json.Unmarshal(k, &e.Items)
这不能解决基础值是非指针的问题。
var a interface{} = &T{}
var b interface{} = T{}
b = &b
a
和b
的类型是不同的,并且将由解组器以不同的方式处理,在b
的情况下,解组者将选择将指向的值替换为map[string]interface{}
。
因此,为了解决您的问题,您可以执行以下操作:
if e.Indicator == "more difficult" {
k = j
e.Items = &Person{}
} else {
e.Items = &[]Person{}
}
return json.Unmarshal(k, e.Items)
答案 1 :(得分:0)
您当前的问题与JSON解组完全无关。
您将Items
定义为interface{}
类型,因此很明显,当您检查它时,它将是interface{}
类型。如果您希望它是[]Person
类型,只需将其定义为:
type Employees struct {
Indicator string `json:"indicator"`
Items []Person `json:"items"`
}
完成后,您的测试用例将产生预期结果。但是您的Items
仍为空,因为您的输入JSON没有items
字段。