簡體   English   中英

Golang 解組 JSON

[英]Golang Unmarshal JSON

我的輸入 JSON 有一個不同元素的列表。
我對響應的第一個元素的數量有問題。

簡化示例

package main

import (
    "fmt"
    "log"
    "encoding/json"
)

var j = ` {
  "response": [
    777, // problem here !!!
    {
      "id": 888,
      "from_id": 999,
      "to_id": 888,
      "text": "hello..."
    },
        {
      "id": 999,
      "from_id": 888,
      "to_id": 999,
            "text": "goodbye..."
    }
  ]
}`

type D struct {
    Id     int `json:"id"`
    FromId int `json:"from_id"`
    ToId   int `json:"to_id"`
    Text   string `json:"text"`
}

type R struct {
    Count    int
    Response []D `json:"response"`
}

func main() {
    var data = new(R)
    err := json.Unmarshal([]byte(j), &data)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(data.Response)
}

輸出錯誤。 我不明白錯誤在哪里。 請幫幫我。


1- 這是工作代碼,在Go Playground上試試:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var d *R
    err := json.Unmarshal([]byte(str), &d)
    if err != nil {
        panic(err)
    }
    var data R2
    data.Count = int(d.Response[0].(float64))

    for _, v := range d.Response[1:] {    
        bs, err := json.Marshal(v)
        if err != nil {
            panic(err)
        }
        var d1 *D
        err = json.Unmarshal(bs, &d1)
        if err != nil {
            panic(err)
        }
        data.Response = append(data.Response, *d1)
    }
    fmt.Println(data)    
}

type R struct {
    Response []interface{} `json:"response"`
}

var str = ` {
  "response": [
    777,  
    {
      "id": 888,
      "from_id": 999,
      "to_id": 888,
      "text": "hello"
    },
        {
      "id": 999,
      "from_id": 888,
      "to_id": 999,
            "text": "goodbye"
    }
  ]
}`

type D struct {
    Id     int    `json:"id"`
    FromId int    `json:"from_id"`
    ToId   int    `json:"to_id"`
    Text   string `json:"text"`
}
type R2 struct {
    Count    int
    Response []D
}

輸出:

{777 [{888 999 888 hello} {999 888 999 goodbye}]}

您的響應 json 無效。 您可以使用數組而不是結構體來指定類型為 D 的字段。

我有不同的方法: https : //play.golang.org/p/9Xnxk7t​​VxE

您所要做的就是實現Unmarshaler接口並在方法 UnmarshalJSON 中添加邏輯。 這是一個與另一個類似的解決方案,但它更便攜,因為你不必在主要或外部方法中這樣做,而且它更健壯一點:)

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

var j = `{
  "response": [
    777,
    {
      "id": 888,
      "from_id": 999,
      "to_id": 888,
      "text": "hello..."
    },
    {
      "id": 999,
      "from_id": 888,
      "to_id": 999,
            "text": "goodbye..."
    }
  ]
}`

type D struct {
    Id     int    `json:"id"`
    FromId int    `json:"from_id"`
    ToId   int    `json:"to_id"`
    Text   string `json:"text"`
}

type R struct {
    Count    int
    Response []D
}

func (r *R) UnmarshalJSON(data []byte) error {
    var values struct {
        Resp []interface{} `json:"response"`
    }

    if err := json.Unmarshal(data, &values); err != nil {
        return err
    }

    if len(values.Resp) < 1 {
        return fmt.Errorf("empty response %v", values.Resp)
    }

    count, isNumber := values.Resp[0].(float64)
    if !isNumber {
        return fmt.Errorf("first element has to be a number, we got '%T'", values.Resp[0])
    }
    r.Count = int(count)

    for _, elem := range values.Resp[1:] {
        de, err := json.Marshal(elem)
        if err != nil {
            return err
        }
        var d D
        if err := json.Unmarshal(de, &d); err != nil {
            return err
        }
        r.Response = append(r.Response, d)
    }
    return nil
}

func main() {
    var data = new(R)
    if err := json.Unmarshal([]byte(j), &data); err != nil {
        log.Fatal(err)
    }
    fmt.Println(*data)
}

暫無
暫無

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

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