La traduction de l'article a été préparée spécialement pour les futurs étudiants du cours "Golang Developer. Professional" .
Les options sont l'un des types de données les plus courants stockés dans les fichiers de configuration . Dans cet article, je couvrirai certaines des nuances à prendre en compte lors du stockage d'options dans JSON et de leur démarshaling dans Go.
En particulier, la différence la plus importante entre les options et toutes les autres données est que les options sont souvent, pardonnez le jeu de mots ... facultatives . Notre programme peut avoir un grand nombre de toutes sortes de paramètres de configuration (options), mais nous pouvons avoir besoin de lancer une invocation spécifique avec seulement un sous-ensemble limité d'entre eux, en laissant les valeurs par défaut pour tout le reste.
Principes de base - Champs Anmarshaling partiel, Omitempty et inconnu
. , :
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 , (, , ). - . , , , .