2017-08-24 12 views
0

私はこのコードを持っている:JSON非整列化不規則なJSONフィールド

type Response struct { 
    ID string `json:"id"` 
    Tags Tags `json:"tags,omitempty"` 
} 

type Tags struct { 
    Geo  []string `json:"geo,omitempty"` 
    Keyword []string `json:"keyword,omitempty"` 
    Storm []string `json:"storm,omitempty"` 
} 

func (t *Tags) UnmarshalJSON(b []byte) (err error) { 
    str := string(b) 
    if str == "" { 
     t = &Tags{} 
     return nil 
    } 

    err = json.Unmarshal(b, t) 
    if err != nil { 
     return err 
    } 

    return nil 
} 

は今、私のJSON応答は次のようになります。

[{ 
    "id": "/cms/v4/assets/en_US", 
    "doc": [{ 
      "id": "af02b41d-c2c5-48ec-9dbc-ceed693bdbac", 
      "tags": { 
       "geo": [ 
        "DMA:US.740:US" 
       ] 
      } 
     }, 
     { 
      "id": "6a90d9ed-7978-4c18-8e36-c01cf4260492", 
      "tags": "" 
     }, 
     { 
      "id": "32cfd045-98ac-408c-b464-c74e02466339", 
      "tags": { 
       "storm": [ 
        "HARVEY - AL092017" 
       ], 
       "keyword": [ 
        "hurrcane", 
        "wunderground" 
       ] 
      } 
     } 
    ] 
}] 

好ましくは、私が正しく行われるようにJSONレスポンスを変更したいです、でも、私は出来ません。マーシャリング解除でエラーが引き続き発生します(goroutine stack exceeds 1000000000-byte limit)。好ましくは、私はむしろeasyjsonまたはffjsonを使用してこれを行うだろうが、それは可能であると疑う。提案?

+1

[JSON-to-Go](https://mholt.github.io/json-to-go/)をご覧ください。私はあなたのjsonを貼り付け、出力は正しい軌道にあった。それはちょうど '嵐'と 'キーワード'フィールドを欠場しました。 – Gavin

+0

私はJSON-to-Goが好きで、過去にそれを使ってきました。私は構造体を探しているわけではありませんが、構造体へのJSONのアンマーシャリングの助けを必要としています。 –

+1

UnmarshalJSONは通常、空のスライスを受け取りません。少なくとも '[]'、 '{}'、 '' '、' 0'のようなものです。一般的に、これを行うために文字列に変換しないでください。 'len(b)== 0'が好ましい。 – Peter

答えて

0

UnmarshalJSON関数は、スタックを爆発的に再帰的に呼び出します。あなたはUnmarshalJSON関数内からjson.Unmarshalを呼び出すための理由がある場合

func (t *Tags) UnmarshalJSON(b []byte) (err error) { 
    str := string(b) 
    if str == "" { 
     t = &Tags{} 
     return nil 
    } 

    err = json.Unmarshal(b, t) <--- here it calls itself again 
    if err != nil { 
     return err 
    } 

    return nil 
} 

が、それは別の種類でなければなりません。これを行うための一般的な方法は、ローカルの別名を使用することです:

type tagsAlias Tags 
    var ta = &tagsAlias 
    err = json.Unmarshal(b, ta) 
    if err != nil { 
     return err 
    } 

    *t = Tags(ta) 

はまたt = &Tags{}があなたの関数内で何もしないことに注意します。新しい値がtに割り当てられますが、その値は関数が終了するとすぐに失われます。 tに本当に割り当てたい場合は、*tが必要です。以前に設定した*Tagsのインスタンスの設定を解除しようとしている場合を除いて、それはまったく必要ありません。

関連する問題