web-dev-qa-db-fra.com

Comment spécifier des valeurs par défaut lors de l'analyse JSON dans Go

Je veux analyser un objet JSON dans Go, mais je veux spécifier des valeurs par défaut pour les champs qui ne sont pas donnés. Par exemple, j'ai le type struct:

type Test struct {
    A string
    B string
    C string
}

Les valeurs par défaut pour A, B et C sont respectivement "a", "b" et "c". Cela signifie que lorsque j'analyse le json:

{"A": "1", "C": 3}

Je veux obtenir la structure:

Test{A: "1", B: "b", C: "3"}

Est-ce possible en utilisant le package intégré encoding/json? Sinon, existe-t-il une bibliothèque Go dotée de cette fonctionnalité?

20
JW.

Ceci est possible en utilisant l'encodage/json: lorsque vous appelez json.Unmarshal, Vous n'avez pas besoin de lui donner une structure vide, vous pouvez lui en donner une avec des valeurs par défaut.

Pour votre exemple:

var example []byte = []byte(`{"A": "1", "C": "3"}`)

out := Test{
    A: "default a",
    B: "default b",
    // default for C will be "", the empty value for a string
}
err := json.Unmarshal(example, &out) // <--
if err != nil {
    panic(err)
}
fmt.Printf("%+v", out)

Courir cet exemple dans la cour de récréation Go renvoie {A:1 B:default b C:3}.

Comme vous pouvez le voir, json.Unmarshal(example, &out) démasque le JSON en out, écrasant les valeurs spécifiées dans le JSON, mais laissant les autres champs inchangés.

55
JW.

Dans le cas où vous avez une liste ou une carte des structures Test, la réponse acceptée n'est plus possible mais elle peut facilement être étendue avec une méthode UnmarshalJSON:

func (t *Test) UnmarshalJSON(data []byte) error {
  type testAlias Test
  test := &testAlias{
    B: "default B",
  }

  _ = json.Unmarshal(data, test)

  *t = Test(*test)
  return nil
}

Le testAlias ​​est nécessaire pour empêcher les appels récursifs à UnmarshalJSON. Cela fonctionne car un nouveau type n'a aucune méthode définie.

https://play.golang.org/p/qiGyjRbNHg

9
Christian