Je veux écrire une fonction qui reçoit plusieurs types de structures et les dissocie de JSON. À cette fin, j'ai un autre ensemble de fonctions avec une signature prédéfinie qui renvoie les instances de struct mais comme chaque fonction renvoie un type de structure différent, la signature de la fonction a le type de retour interface{}
. Quand j'envoie json.Unmarshal une structure concrète fonctionne comme je m'y attendais mais quand j'envoie la même structure que interface{}
, elle le convertit en une carte.Comment dire à json.Unmarshal d'utiliser struct à la place de l'interface
Voici un code d'exemple simplifié qui représente le problème:
package main
import (
"encoding/json"
"fmt"
)
type Foo struct {
Bar string `json:"bar"`
}
func getFoo() interface{} {
return Foo{"bar"}
}
func main() {
fooInterface := getFoo()
fooStruct := Foo{"bar"}
fmt.Println(fooInterface) //{bar}
fmt.Println(fooStruct) //{bar}
myJSON := `{"bar":"This is the new value of bar"}`
jsonBytes := []byte(myJSON)
err := json.Unmarshal(jsonBytes, &fooInterface)
if err != nil {
fmt.Println(err)
}
fmt.Println(fooInterface) //map[bar:This is the new value of bar]
err = json.Unmarshal(jsonBytes, &fooStruct)
if err != nil {
fmt.Println(err)
}
fmt.Println(fooStruct) //{This is the new value of bar}
}
https://play.golang.org/p/tOO7Ki_i4c
Je pensais json.Unmarshal utiliser la structure en béton derrière l'interface pour unmarshaling mais il n'a pas seulement et ayants droit la carte des valeurs à l'interface passée.
Pourquoi n'utilise-t-il pas la structure concrète et existe-t-il un moyen de lui dire d'utiliser le type de structure béton sans cast explicite (je ne connais pas le type explicite au moment du design)?
Voulez-vous dire que je ne peux pas extraire le type concret d'une interface (comme encoding/json ne peut pas le faire non plus)? – Buzzy
@Buzzy Oui, vous pouvez. Mais vous avez passé '* interface {}'. Voir la réponse éditée. – icza
Merci! Votre explication était claire et utile – Buzzy