JSON dengan kolom opsional di Go

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, .

. :

  1. JSON- , , Go .

  2. 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 , (, , ). - . , , , .

.




All Articles