Historique de la question :
En Go, il n'y a pas de conteneurs universels de type map générique par défaut — ce n'est qu'à partir de Go 1.18 que des generics ont été introduits, mais pour des structures dynamiques, on utilise souvent map[string]interface{} depuis toujours, ce qui permet de stocker des valeurs de n'importe quel type par clé de chaîne.
Problème :
Ce motif — équivalent d'un dictionnaire/objet JSON, se rencontre partout pour la sérialisation, le travail avec des middleware, des données sans structure définie (comme l'analyse JSON via encoding/json). Cependant, l'accès aux valeurs nécessite une conversion de type manuelle et de la prudence avec les valeurs implicites et l'absence de clés.
Solution :
Utilisez map[string]interface{} là où la structure des données d'entrée est inconnue. Vérifiez soigneusement la présence de la clé, effectuez la conversion de type (assertion de type) uniquement après l'idiome exists. Il est préférable de ne pas garder de telles maps "profondément" dans la logique métier, mais comme adaptateur aux frontières du système.
Exemple de code :
obj := map[string]interface{}{ "int": 42, "str": "bonjour", "flag": true, } if v, ok := obj["int"]; ok { n, success := v.(int) if success { fmt.Println(n) } }
Caractéristiques clés :
Peut-on accéder à une valeur par clé dans map[string]interface{} sans erreur si la clé est absente ?
Non, cela donnera "zero value" (nil) pour interface{}, la conversion en type spécifique provoquera une panique.
Que se passe-t-il lors de la sérialisation de map[string]interface{} avec des slices imbriqués ou d'autres maps ?
La sérialisation JSON traitera correctement la structure, mais si des types non pris en charge par défaut (comme les types, les canaux, les fonctions) sont présents, cela entraînera une erreur de marshalling.
Peut-on comparer deux valeurs dans map[string]interface{} avec == ?
Non, interface{} peut être comparé uniquement si la valeur sous-jacente est comparable. Si une map ou un slice est testé, cela provoquera une panique.
Dans l'application, toute la logique est basée sur des objets map[string]interface{}, chaque contrôleur/service les transmet profondément à travers les appels.
Avantages :
Inconvénients :
Utiliser map[string]interface{} uniquement pour travailler avec des interfaces externes, des données d'entrée/sortie, puis les convertir en structures normales.
Avantages :
Inconvénients :