A tradução do artigo foi preparada especialmente para futuros alunos do curso "Golang Developer. Professional" .
Um dos tipos mais comuns de dados armazenados em arquivos de configuração são opções . Neste artigo, falarei sobre algumas das nuances a serem consideradas ao armazenar opções em JSON e desempacotá-las no Go.
Em particular, a diferença mais importante entre opções e quaisquer outros dados é que as opções são frequentemente, com o perdão do trocadilho ... opcionais . Nosso programa pode ter um grande número de todos os tipos de parâmetros de configuração (opções), mas podemos precisar iniciar qualquer invocação específica com apenas um subconjunto limitado deles, deixando os valores padrão para todo o resto.
Básico - Campos Parciais Anmarshaling, Omitempty e Desconhecidos
. , :
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 , (, , ). - . , , , .