Terjemahan artikel disiapkan khusus untuk calon siswa kursus "Pengembang Golang. Profesional" .
Salah satu jenis data paling umum yang disimpan dalam file konfigurasi adalah opsi . Dalam artikel ini, saya akan membahas beberapa hal yang perlu dipertimbangkan saat menyimpan opsi di JSON dan membatalkannya di Go.
Secara khusus, perbedaan terpenting antara opsi dan data lainnya adalah bahwa opsi sering kali, maafkan kata-kata ... opsional . Program kita dapat memiliki semua jenis parameter konfigurasi (opsi) dalam jumlah besar, tetapi kita mungkin perlu memulai pemanggilan tertentu dengan hanya subset terbatas, meninggalkan nilai default untuk yang lainnya.
Dasar - Bidang Anmarshaling Parsial, Kosong, dan Tidak Dikenal
. , :
type Options struct {
Id string `json:"id,omitempty"`
Verbose bool `json:"verbose,omitempty"`
Level int `json:"level,omitempty"`
Power int `json:"power,omitempty"`
}4 , .
, JSON- . :
{
"id": "foobar",
"verbose": false,
"level": 10,
"power": 221
} , . json.Unmarshal, .
. :
JSON- , , Go .
JSON- , . , .
(1) json Go , JSON; Go. , JSON level, Options Level 0. , .
(2) json . , JSON:
{
"id": "foobar",
"bug": 42
}json.Unmarshal Options, Id "foobar", Level Power 0, Verbose false. bug.
, - . , json , JSON- DisallowUnknownFields:
dec := json.NewDecoder(bytes.NewReader(jsonText))
dec.DisallowUnknownFields()
var opts Options
if err := dec.Decode(&opts2); err != nil {
fmt.Println("Decode error:", err)
}JSON .
, , Options omitempty, . , JSON. :
opts := Options{
Id: "baz",
Level: 0,
}
out, _ := json.MarshalIndent(opts, "", " ")
fmt.Println(string(out)):
{
"id": "baz"
}. , omitempty.
, JSON- Go. , , . , Power 10, 0? , JSON Β«powerΒ», Power 10, Unmarshal .
- ! Power 10 , JSON 0! . , JSON 0?
, . , json.Unmarshal :
func parseOptions(jsn []byte) Options {
opts := Options{
Verbose: false,
Level: 0,
Power: 10,
}
if err := json.Unmarshal(jsn, &opts); err != nil {
log.Fatal(err)
}
return opts
} json.Unmarshal Options, parseOptions.
UnmarshalJSON Options:
func (o *Options) UnmarshalJSON(text []byte) error {
type options Options
opts := options{
Power: 10,
}
if err := json.Unmarshal(text, &opts); err != nil {
return err
}
*o = Options(opts)
return nil
} json.Unmarshal Options Power . options - UnmarshalJSON.
, . -, . , , ; .
, . Options , . :
type Region struct {
Name string `json:"name,omitempty"`
Power int `json:"power,omitempty"`
}
type Options struct {
Id string `json:"id,omitempty"`
Verbose bool `json:"verbose,omitempty"`
Level int `json:"level,omitempty"`
Power int `json:"power,omitempty"`
Regions []Region `json:"regions,omitempty"`
} Power Region, Options. Region. - UnmarshalJSON .
, . -.
-
Options :
type Options struct {
Id *string `json:"id,omitempty"`
Verbose *bool `json:"verbose,omitempty"`
Level *int `json:"level,omitempty"`
Power *int `json:"power,omitempty"`
}, , . , JSON:
{
"id": "foobar",
"verbose": false,
"level": 10
}, , "power". :
var opts Options
if err := json.Unmarshal(jsonText, &opts); err != nil {
log.Fatal(err)
} , ( nil ), , ( ). , Options :\
func parseOptions(jsn []byte) Options {
var opts Options
if err := json.Unmarshal(jsonText, &opts); err != nil {
log.Fatal(err)
}
if opts.Power == nil {
var v int = 10
opts.Power = &v
}
return opts
} , opts.Power; , Go , , int. , , :
func Bool(v bool) *bool { return &v }
func Int(v int) *int { return &v }
func String(v string) *string { return &v }
// .. ... , opts.Power = Int(10).
, , JSON. Options , , nil.
- Β« Β»? . , , , . Protobuf protobuf- proto2, . !
, . , , Go , (, , ). - . , , , .