La traducción del artículo fue preparada especialmente para futuros alumnos del curso "Golang Developer. Professional" .
Uno de los tipos de datos más comunes almacenados en archivos de configuración son las opciones . En este artículo, cubriré algunos de los matices a considerar al almacenar opciones en JSON y desagruparlas en Go.
En particular, la diferencia más importante entre las opciones y cualquier otro dato es que las opciones son a menudo, perdón el juego de palabras ... opcionales . Nuestro programa puede tener una gran cantidad de todo tipo de parámetros de configuración (opciones), pero es posible que necesitemos iniciar cualquier invocación específica con solo un subconjunto limitado de ellos, dejando los valores predeterminados para todo lo demás.
Conceptos básicos: campos anómalos parciales, omniscientes y desconocidos
. , :
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 , (, , ). - . , , , .