encoding/json dengan Struct
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 76 dari 107.
Package encoding/json memungkinkan kamu mengonversi struct Go ke JSON dan sebaliknya. Ini penting untuk API, file konfigurasi, dan penyimpanan data. Tag struct mengatur pemetaan field ke kunci JSON.
Untuk mengonversi struct menjadi JSON, gunakan json.Marshal:
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
}
func main() {
user := User{Name: "Alice", Email: "alice@example.com", Age: 30}
data, _ := json.Marshal(user)
fmt.Println(string(data))
// {"name":"Alice","email":"alice@example.com","age":30}
}Tag struct seperti `json:"name"` menentukan nama key JSON. Tanpa tag, Go menggunakan nama field secara langsung. Hanya field yang diekspor (diawali huruf kapital) yang disertakan dalam output JSON.
Untuk mengonversi JSON kembali menjadi struct, gunakan json.Unmarshal:
jsonStr := `{"name":"Bob","email":"bob@example.com","age":25}`
var user User
json.Unmarshal([]byte(jsonStr), &user)
fmt.Println(user.Name) // BobOpsi tag yang umum mencakup omitempty untuk melewati nilai nol dan - untuk mengabaikan seluruh field:
type Product struct {
ID int `json:"id"`
Name string `json:"name"`
Price float64 `json:"price,omitempty"`
Internal string `json:"-"`
}Dengan omitempty, jika Price bernilai nol, field tersebut tidak akan muncul dalam JSON. Field Internal tidak pernah disertakan, apa pun nilainya.
Tantangan
MudahMari kita buat sistem katalog film yang mengonversi antara struct Go dan JSON! Kamu akan berlatih melakukan marshaling struct ke JSON dan unmarshaling JSON kembali menjadi struct, menggunakan tag struct untuk mengatur nama field JSON.
Kamu akan mengatur kodemu dalam dua file:
movie.go: Definisikan model data film dengan tag JSON yang sesuai.Buat struct
Moviedengan field dan pemetaan JSON berikut:Title(string) dipetakan ke"title"Director(string) dipetakan ke"director"Year(int) dipetakan ke"year"Rating(float64) dipetakan ke"rating"denganomitemptyagar film yang belum memiliki rating tidak menampilkan field ratingInternalID(string) harus sepenuhnya dikecualikan dari JSON menggunakan"-"
Buat fungsi
ToJSON(m Movie) stringyang mengonversi Movie menjadi string JSON. Buat jugaFromJSON(jsonStr string) Movieyang mengurai string JSON kembali menjadi struct Movie.main.go: Tunjukkan konversi JSON dalam kedua arah.Baca tipe operasi (
encodeataudecode).Untuk
encode: Baca detail film (title, director, year, rating) pada baris terpisah. Buat Movie dengan InternalID bernilai"internal-123", konversikan menjadi JSON, lalu cetak hasilnya.Untuk
decode: Baca string JSON, konversikan menjadi struct Movie, lalu cetak detail film dalam format ini:Title: [title] Director: [director] Year: [year] Rating: [rating]Tampilkan rating dengan satu angka desimal. Jika rating bernilai 0 (tidak ada di JSON), cetak
Rating: N/A.
Input berikut akan diberikan:
- Baris 1: Tipe operasi (
encodeataudecode) - Untuk encode: title, director, year, rating (empat baris)
- Untuk decode: string JSON (satu baris)
Contohnya, jika diberikan:
encode
Inception
Christopher Nolan
2010
8.8Outputmu seharusnya:
{"title":"Inception","director":"Christopher Nolan","year":2010,"rating":8.8}Perhatikan bahwa InternalID tidak muncul dalam output karena tag "-".
Jika diberikan:
encode
The Matrix
Wachowskis
1999
0Outputmu seharusnya:
{"title":"The Matrix","director":"Wachowskis","year":1999}Perhatikan bahwa rating tidak disertakan karena nilainya nol dan memiliki omitempty.
Jika diberikan:
decode
{"title":"Interstellar","director":"Christopher Nolan","year":2014,"rating":8.6}Outputmu seharusnya:
Title: Interstellar
Director: Christopher Nolan
Year: 2014
Rating: 8.6Jika diberikan:
decode
{"title":"Tenet","director":"Christopher Nolan","year":2020}Outputmu seharusnya:
Title: Tenet
Director: Christopher Nolan
Year: 2020
Rating: N/ACoba sendiri
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Baca jenis operasi
operation, _ := reader.ReadString('\n')
operation = strings.TrimSpace(operation)
if operation == "encode" {
// Baca detail film
title, _ := reader.ReadString('\n')
title = strings.TrimSpace(title)
director, _ := reader.ReadString('\n')
director = strings.TrimSpace(director)
yearStr, _ := reader.ReadString('\n')
yearStr = strings.TrimSpace(yearStr)
year, _ := strconv.Atoi(yearStr)
ratingStr, _ := reader.ReadString('\n')
ratingStr = strings.TrimSpace(ratingStr)
rating, _ := strconv.ParseFloat(ratingStr, 64)
// TODO: Buat struct Movie dengan nilai yang dibaca
// Atur InternalID ke "internal-123"
// Ubah menjadi JSON menggunakan ToJSON, lalu cetak hasilnya
} else if operation == "decode" {
// Baca string JSON
jsonStr, _ := reader.ReadString('\n')
jsonStr = strings.TrimSpace(jsonStr)
// TODO: Ubah JSON menjadi Movie menggunakan FromJSON
// Cetak detail film dalam format yang diminta
// Gunakan fmt.Sprintf("%.1f", rating) untuk memformat rating
// Jika rating bernilai 0, cetak "Rating: N/A" sebagai gantinya
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP di Go
File EksternalWorkspace Go dan modulePaket dan ImporNama yang Diekspor dan Tidak DieksporPengantar OOP di Gostruct sebagai classMendefinisikan method pada structPointer receiver vs value receiverInisialisasi structFungsi KonstruktorUlasan: Kalkulator Sederhana4Interface
Pengenalan InterfaceImplementasi ImplisitInterface sebagai KontrakInterface Kosong (any)Type AssertionType SwitchKomposisi InterfaceInterface Stringer & ErrorUlasan: Kalkulator Bentuk7Enkapsulasi
Field yang Diekspor vs Tidak DieksporEnkapsulasi Tingkat PackageMethod Getter dan SetterPenyembunyian Informasi di GoRingkasan: Data Siswa10Generics (Go 1.18+)
Pengantar GenericsParameter TipeBatasan TipeStruct GenerikCara Alternatif untuk Method GenerikRingkasan Koleksi Generik2Mendalami Tipe dan Struct
Tipe Dasar dan KompositDefinisi Tipe KustomTag StructStruct AnonimStruct BersarangNilai Nol dan Nilai BawaanRangkuman: Buku Kontak5Komposisi daripada Pewarisan
Mengapa Go Tidak Memiliki PewarisanDasar Penyematan StructPromosi methodMenyematkan Beberapa StructPenyematan vs AgregasiMembayangi method yang DisematkanRangkuman: Hierarki Karyawan8Penanganan Error & OOP
Interface errorTipe Error KustomPembungkusan Error (fmt.Errorf)Error Sentinelerrors.Is() dan errors.As()Panic, Defer, dan RecoverRangkuman: Parser File11Pustaka Standar & OOP
io.Reader & io.Writersort.InterfaceAntarmuka fmt.Stringerencoding/json dengan StructAntarmuka http.HandlerRingkasan, Model REST API3Pointer dan Memori
Dasar-Dasar Pointer di GoPointer ke StructPass by Value vs ReferenceFungsi new()Garbage Collection di GoRekap: Pembuat Linked List6Polimorfisme di Go
Polimorfisme melalui InterfaceDuck Typing di GoAturan Pemenuhan InterfaceKoleksi PolimorfikInjeksi DependensiRangkuman: Pemroses Pembayaran9Konkruensi & OOP
Dasar-dasar GoroutineChannel & KomunikasiChannel Ber-buffer vs Tanpa BufferPernyataan selectsync.Mutex & sync.RWMutexsync.WaitGroupDesain Struct yang Aman untuk ThreadRingkasan: Worker PoolLatihan sendiri: Compiler Go online