Bekerja dengan data JSON selalunya melibatkan penukarannya kepada struct untuk pemprosesan selanjutnya. Walau bagaimanapun, cabaran timbul apabila struct mengandungi medan dengan teg tersuai yang memberi kesan kepada proses unmarshalling. Artikel ini menunjukkan cara mengendalikan senario sedemikian menggunakan keupayaan pantulan Go.
Dalam situasi khusus ini, matlamatnya adalah untuk menyahmarshal data JSON ke dalam struct di mana salah satu medannya mempunyai teg yang menunjukkan ia harus dianggap sebagai rentetan JSON. Mari kita pertimbangkan contoh ini:
<code class="go">const data = `{ "I": 3, "S": { "phone": { "sales": "2223334444" } } }` type A struct { I int64 S string `sql:"type:json"` }</code>
Dalam kes ini, matlamatnya ialah untuk menyahmarshal medan "S" dalam JSON sebagai rentetan ke dalam struct A.
Go menyediakan kaedah UnmarshalJSON terbina dalam yang membenarkan tingkah laku unmarshalling tersuai. Dengan mencipta jenis baharu, melaksanakan kaedah MarshalJSON dan UnmarshalJSON, kami boleh mencapai hasil yang diingini:
<code class="go">import ( "encoding/json" "errors" "log" "fmt" ) // RawString is a raw encoded JSON object. // It implements Marshaler and Unmarshaler and can // be used to delay JSON decoding or precompute a JSON encoding. type RawString string // MarshalJSON returns *m as the JSON encoding of m. func (m *RawString) MarshalJSON() ([]byte, error) { return []byte(*m), nil } // UnmarshalJSON sets *m to a copy of data. func (m *RawString) UnmarshalJSON(data []byte) error { if m == nil { return errors.New("RawString: UnmarshalJSON on nil pointer") } *m += RawString(data) return nil } const data = `{"i": 3, "S": {"phone": {"sales": "2223334444"}}}` type A struct { I int64 S RawString `sql:"type:json"` } func main() { a := A{} err := json.Unmarshal([]byte(data), &a) if err != nil { log.Fatal("Unmarshal failed", err) } fmt.Println("Done", a) }</code>
Dalam penyelesaian ini, jenis RawString melaksanakan kaedah MarshalJSON dan UnmarshalJSON untuk mengawal cara data JSON dikodkan dan dinyahkodkan, pada asasnya membenarkan medan "S" dianggap sebagai rentetan semasa unmarshalling.
Dengan memanfaatkan keupayaan refleksi Go dan kaedah unmarshalling tersuai, adalah mungkin untuk mengendalikan senario unmarshalling JSON yang kompleks walaupun apabila medan mempunyai teg khusus yang memerlukan rawatan khas.
Atas ialah kandungan terperinci Bagaimanakah anda menyahmarshal data JSON dengan teg medan tersuai dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!