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