Nama kunci JSON huruf kecil dengan JSON Marshal in Go

175

Saya ingin menggunakan "encoding/json"paket untuk menyusun struct yang dideklarasikan di salah satu paket impor aplikasi saya.

Misalnya.:

type T struct {
    Foo int
}

Karena itu diimpor, semua bidang yang tersedia (diekspor) di struct dimulai dengan huruf besar. Tapi saya ingin memiliki nama kunci huruf kecil:

out, err := json.Marshal(&T{Foo: 42})

akan menghasilkan

{"Foo": 42}

tapi saya ingin mendapatkannya

{"foo": 42}

Apakah mungkin untuk menyelesaikan masalah dengan cara yang mudah?

Anisus
sumber
5
@ Zipoxer: Saya akan mengatakan: kunci dalam protokol komunikasi klien / server secara ketat didefinisikan untuk huruf kecil. Nah, dalam kasus saya itu tidak masalah karena saya telah mendefinisikan protokol sendiri .. tetapi dalam teori setidaknya? Tapi, saya tahu itu terutama hanya saya menghabiskan terlalu banyak waktu pada detail kecil yang konyol.
ANisus
Jangan minta maaf. Anda bukan yang konyol, bahasa yang tidak menerima spesifikasi json penuh adalah yang konyol (meskipun masalah ini mudah diselesaikan, seperti di bawah ini).
Jehan
@Anisus: Saya salah membaca pertanyaan Anda tentang nama kunci struct, bukan nama kunci JSON. Menarik kembali pemungutan suara.
Flimzy

Jawaban:

266

Lihatlah dokumen untuk enkode / json.Marshal . Ini membahas menggunakan tag bidang struct untuk menentukan bagaimana json yang dihasilkan diformat.

Sebagai contoh:

type T struct {
    FieldA int    `json:"field_a"`
    FieldB string `json:"field_b,omitempty"`
}

Ini akan menghasilkan JSON sebagai berikut:

{
    "field_a": 1234,
    "field_b": "foobar"
}
Jim
sumber
8
Tag bidang? Ya ampun .. Aku merindukan seluruh bagian ini ketika mencari di dokumen. Saya mencari flag, fungsi atau pengaturan lainnya. Nah, inilah jawaban tepat yang saya cari! Dan selain itu, saya memiliki konsep Go baru untuk belajar tentang: tag lapangan :)
ANisus
Mereka sangat berguna. Anda dapat mengaksesnya saat runtime melalui reflectpaket.
hanya
Ya, ketika bekerja dengan refleksi saya melihat bagaimana memiliki cara untuk menambahkan data meta ke bidang bisa menjadi hal yang luar biasa! Btw, baru mencoba jawabannya. Bekerja seperti pesona.
ANisus
5
Saya baru saja mulai mengutuk bahasa go - betapa bodohnya ini, mengapa mereka membuat bidang dengan huruf kecil di JSON yang dihasilkan dll, dll. Lalu saya menemukan utas ini dan berpikir "OMG Itu brilian !!!". Saya bahkan melompat dan menjelaskan pacar saya mengapa saya sangat bersemangat: D Ini sangat keren :)))
nyxz
11
Pastikan tidak ada ruang di antara titik dua dan tanda kutip pertama dari tag! Gunakan json:"some_tag"sebagai ganti json: "some_tag". Saya mendapat sedikit dengan ini untuk sementara waktu.
David Morales
8

Anda bisa membuat struct sendiri dengan kunci yang ingin Anda ekspor, dan memberi mereka tag json yang sesuai untuk nama huruf kecil. Kemudian Anda dapat menyalin struct yang diinginkan ke dalam milik Anda sebelum menyandikannya sebagai JSON. Atau jika Anda tidak ingin repot membuat struct lokal, Anda mungkin bisa membuat map[string]interface{}dan menyandikannya.

Lily Ballard
sumber
Yang konyol adalah bahwa paket lain (berisi jenis) sebenarnya milik saya juga. Tapi, ya, saya mungkin telah membabi buta melihat fakta bahwa itu pasti sebuah struct. Menggunakan map[string]interface{}akan bekerja selama saya tidak berakhir dengan objek / struct bersarang
ANisus
1
@Anisus: Oh, jawaban saya didasarkan pada Anda tidak bisa mengendalikan definisi struct. Jawaban Jim adalah pasti apa yang Anda inginkan.
Lily Ballard
Ya, saya tidak jelas apakah itu paket eksternal atau tidak. Tetapi jawaban Anda masih relevan dan berguna dalam kasus-kasus ketika Anda tidak mengontrol definisi.
ANisus