Go構造体をJSONに変換する


181

jsonパッケージを使用してGo構造体をJSONに変換しようとしていますが、取得できるのはだけ{}です。まったく明白なことだと思いますが、わかりません。

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func main() {
    user := &User{name:"Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Printf("Error: %s", err)
        return;
    }
    fmt.Println(string(b))
}

それを実行しようとすると、次のようになります。

$ 6g test.go && 6l -o test test.6 && ./test 
{}

回答:


331

パッケージが表示できるようにフィールドをエクスポートする必要があります。フィールドの名前をに変更します。User.namejsonnameName

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    Name string
}

func main() {
    user := &User{Name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}

出力:

{"Name":"Frank"}

87
`json:"name"`構造体フィールド定義の最後に追加して、出力名を保持できることに注意してください。
ダスティン

12
そうですか。私は少し言語が好きですが、いくつかの構文要素は遠いところに行きます。構造体メンバーの名前が動作を決定する場合、これは単に間違っています。
magiconair

1
まあ、名前が振る舞いを決定するかどうかは、それが良いか悪いかについて議論することができます:)しかし、それは確かに他の場所をチェックする必要なしにフィールドがエクスポートされているかどうかを簡単に知ることができます。
オロフ

6
@magiconair:最初のルーンの大文字化は可視性を決定し「構造体メンバーの名前が動作を決定する」よりもはるかに合理的なアイデアです。可視性メタデータはどこかに保存する必要があり、それを表現する構文が必要です。最終的に、最初のcharの大文字の選択は、トレードオフが最も少ない場合に最も効果的であると判断されました。Go1リリースの前に、他のスキームが試行され、拒否されました。
deft_code

11
私はそれから長い道のりを歩んできました、そして今、大文字による輸出を含む言語がとても好きです。
magiconair 2014年

62

関連する問題:

構造体をJSONに変換し、それをGolangからの応答として送信するのに問題があり、その後、Ajaxを介してJavaScriptで同じものをキャッチしました。

多くの時間を無駄にしたので、ここに解決策を投稿します。

移動中:

// web server

type Foo struct {
    Number int    `json:"number"`
    Title  string `json:"title"`
}

foo_marshalled, err := json.Marshal(Foo{Number: 1, Title: "test"})
fmt.Fprint(w, string(foo_marshalled)) // write response to ResponseWriter (w)

JavaScriptの場合:

// web call & receive in "data", thru Ajax/ other

var Foo = JSON.parse(data);
console.log("number: " + Foo.number);
console.log("title: " + Foo.title);

これが誰かを助けることを願っています。
幸運を祈ります。


6

構造体の値はJSONオブジェクトとしてエンコードされます。次の場合を除いて、エクスポートされた各構造体フィールドはオブジェクトのメンバーになります。

  • フィールドのタグが「-」、または
  • フィールドは空で、そのタグは「omitempty」オプションを指定します。

空の値は、false、0、nilポインターまたはインターフェイスの値、および長さ0の配列、スライス、マップ、または文字列です。オブジェクトのデフォルトのキー文字列は構造体フィールド名ですが、構造体フィールドのタグ値で指定できます。構造体フィールドのタグ値の「json」キーはキー名で、その後にオプションのコンマとオプションが続きます。


2

独自のカスタムMarshalJSONおよびUnmarshalJSONメソッドを定義し、何を含めるかを意図的に制御できます。例:

package main

import (
    "fmt"
    "encoding/json"
)

type User struct {
    name string
}

func (u *User) MarshalJSON() ([]byte, error) {
    return json.Marshal(&struct {
        Name     string `json:"name"`
    }{
        Name:     "customized" + u.name,
    })
}

func main() {
    user := &User{name: "Frank"}
    b, err := json.Marshal(user)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(b))
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.