Konversi Go struct ke JSON

181

Saya mencoba mengonversi Go struct ke JSON menggunakan jsonpaket tetapi yang saya dapatkan hanyalah {}. Saya yakin itu adalah sesuatu yang sangat jelas tetapi saya tidak melihatnya.

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))
}

Lalu ketika saya mencoba menjalankannya saya mendapatkan ini:

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

Jawaban:

331

Anda perlu mengekspor dalam User.namebidang sehingga jsonpaket dapat melihatnya. Ganti nama namebidang menjadi Name.

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))
}

Keluaran:

{"Name":"Frank"}
peterSO
sumber
87
Perhatikan bahwa Anda dapat menambahkan `json:"name"`ke akhir definisi bidang struct untuk mempertahankan nama output.
Dustin
12
Saya melihat. Saya agak suka bahasanya tetapi saya pikir beberapa elemen sintaksis berjalan jauh. Jika nama anggota struct menentukan perilaku maka ini hanya salah.
magiconair
1
Nah, memiliki nama menentukan perilaku dapat diperdebatkan apakah itu baik atau buruk :) tapi itu pasti membuatnya mudah untuk mengetahui apakah suatu bidang diekspor atau tidak tanpa harus memeriksa tempat lain.
Olof
6
@magiconair: Kapitalisasi huruf pertama menentukan visibilitas , adalah ide yang jauh lebih masuk akal daripada, "nama anggota struct menentukan perilaku" . Metadata visibilitas perlu disimpan di suatu tempat dan perlu sintaks untuk mengekspresikannya. Akhirnya ditentukan bahwa memilih kapitalisasi dari char pertama bekerja paling baik dengan trade-off paling sedikit. Sebelum rilis Go1 skema lain dicoba dan ditolak.
deft_code
11
Saya telah datang jauh sejak dan menyukai bahasa termasuk mengekspor dengan huruf kapital sekarang.
magiconair
62

Masalah terkait:

Saya mengalami masalah saat mengubah struct ke JSON, mengirimkannya sebagai respons dari Golang, kemudian, menangkap yang sama di JavaScript melalui Ajax.

Buang banyak waktu, jadi postingkan solusinya di sini.

In Go:

// 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)

Dalam JavaScript:

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

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

Semoga ini bisa membantu seseorang.
Semoga berhasil.

Manohar Reddy Poreddy
sumber
6

Nilai Struct dikodekan sebagai objek JSON. Setiap bidang struct yang diekspor menjadi anggota objek kecuali:

  • tag isian adalah "-", atau
  • bidang ini kosong dan tag-nya menentukan opsi "omitempty".

Nilai kosong adalah false, 0, sembarang nil pointer atau nilai antarmuka, dan setiap array, slice, map, atau string dengan panjang nol. String kunci default objek adalah nama bidang struct tetapi dapat ditentukan dalam nilai tag bidang struct. Kunci "json" dalam nilai tag bidang struct adalah nama kunci, diikuti oleh koma dan opsi opsional.

GoLang Master
sumber
2

Anda dapat menentukan metode MarshalJSON dan UnmarshalJSON kustom Anda sendiri dan dengan sengaja mengontrol apa yang harus dimasukkan, mis:

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))
}
Hieu Vo
sumber