簡體   English   中英

為什么在接口中添加func會導致json.Unmarshal失敗?

[英]Why would adding a func in an interface cause json.Unmarshal to fail?

為什么這失敗並顯示錯誤:

json:無法將對象解組到Go結構字段main.Spouse中的Person.spouse

type Spouse interface {
    Name() // Adding this causes an error
}

type Address interface {
}

type Person struct {
    Name string   `json:"name"`
    A    *Address `json:"address"`
    S    *Spouse  `json:"spouse"`
}

func main() {
    b := []byte(`{
     "name":"sarah", 
     "address":{
         "street":"101 main" 
         }, 
     "spouse":{
         "name":"joe"
         }
     }
    `)

    p := &Person{}
    if err := json.Unmarshal(b, p); err != nil {
        fmt.Printf("%s", err)
    }
}

查看文檔 ,我看不到為什么在接口中添加功能會導致錯誤。 我期望json.Unmarshal只是忽略Name()函數,因為它不是json.Unmarshal處理的列表的一部分。

這是去操場的代碼。

go版本go1.10 darwin / amd64

精美的手冊中

Func Unmarshal
[...]
要將JSON解組為接口值,Unmarshal將其中之一存儲在接口值中:

 bool, for JSON booleans float64, for JSON numbers string, for JSON strings []interface{}, for JSON arrays map[string]interface{}, for JSON objects nil for JSON null 

您正在嘗試將JSON對象解組到接口中,因此該接口后面的值將是map[string]interface{}來表示鍵/值對。 但是map[string]interface{}沒有Name()方法,因此它沒有實現您的Spouse接口。

如果我們稍微簡化一下示例並擺脫Name()方法,我們可以看到發生了什么:

type Spouse interface {
}

type Person struct {
    S *Spouse `json:"spouse"`
}

func main() {
    b := []byte(`{"spouse":{ "name":"joe" } }`)

    p := &Person{}
    if err := json.Unmarshal(b, p); err != nil {
        fmt.Printf("%s", err)
    }
    spouse := (*p.S).(map[string]interface{})
    fmt.Printf("%+v\n", spouse)
}

spousemap[string]interface{}

問題是您正在嘗試使用不匹配的特定數據類型映射json中的spouse值。 本文所述 ,json使用空接口將通用數據類型映射到文件中使用的正確數據類型。

json包使用map[string]interface{}[]interface{}值存儲任意JSON對象和數組; 它將很樂意將任何有效的JSON Blob編組為純interface{}值。 默認的具體Go類型是:

  • bool JSON布爾值,
  • JSON編號的float64
  • string的JSON字符串,
  • nil為JSON空。

如果要從另一個角度看待它,則意味着您不能使用這些數據類型以外的任何其他東西來映射JSON中的數據。 而且您的非空接口不是有效的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM