web-dev-qa-db-ja.com

文字列をjsonまたはstructに変換する

このようなjsonを表す文字列を取得したい:

{"投票":{"option_A": "3"}}

およびその中に「カウント」キーを含めるしたがって、次のように終了します。

{"投票":{"option_A": "3"}、 "count": "1"}

これが、カウントを追加して再び文字列にするために、jsonに変換することを計画した理由です。 問題はそのjsonの構造がわからないです。そのため、その構造が異なるためjson.Unmarshal(in, &myStruct)を使用できません。これどうやってするの?どうもありがとうございました

31
Leticia Esperon

本当に必要なのは単一の構造体だけです。コメントで述べたように、フィールド上の正しい注釈は望ましい結果をもたらします。 JSONは、非常に多様なデータ形式ではなく、明確に定義されており、どんなに複雑で混乱していても、スキーマとGoのオブジェクトの両方で100%の精度でかなり簡単に表現できます。他のほとんどのOOプログラミング言語。以下に例を示します。

package main

import (
    "fmt"
    "encoding/json"
)

type Data struct {
    Votes *Votes `json:"votes"`
    Count string `json:"count,omitempty"`
}

type Votes struct {
    OptionA string `json:"option_A"`
}

func main() {
    s := `{ "votes": { "option_A": "3" } }`
    data := &Data{
        Votes: &Votes{},
    }
    err := json.Unmarshal([]byte(s), data)
    fmt.Println(err)
    fmt.Println(data.Votes)
    s2, _ := json.Marshal(data)
    fmt.Println(string(s2))
    data.Count = "2"
    s3, _ := json.Marshal(data)
    fmt.Println(string(s3))
}

https://play.golang.org/p/ScuxESTW5i

最新のコメントに基づいて、interface{}を使用してカウント以外のデータを表し、カウントを文字列にして、基本的にすべてを受け入れるinterface{}に残りのBLOBを入れることで対処できます。 。そうは言っても、Goはかなり厳密な型システムを持つ静的に型付けされた言語であり、繰り返しになりますが、「何でも構いません」というコメントは真実ではありません。 JSONは何にもできません。 JSONのどの部分にもスキーマがあり、1つのスキーマでJSONの多くのバリエーションを定義できます。データの構造を理解するために時間をかけることをお勧めします。絶対にできるのであれば定義できないという考えの下で何かをハッキングするのではなく、自分が何をしているのかを知っている人にとっては非常に簡単です。

42
evanmcdonnal
package main

import "encoding/json"

func main() {
    in := []byte(`{ "votes": { "option_A": "3" } }`)
    var raw map[string]interface{}
    json.Unmarshal(in, &raw)
    raw["count"] = 1
    out, _ := json.Marshal(raw)
    println(string(out))
}

https://play.golang.org/p/QUyL3cyTAC

63
fsenart