Introduction : pourquoi Go râle-t-il sur vos données ?
\nImaginez : vous codez en Go, tout va bien, mais soudain le compilateur affiche un message glacial : cannot convert data (type interface {}) to type string: need type assertion. Cela vous dit quelque chose ? Si vous avez travaillé avec Go ne serait-ce qu'une semaine, cette erreur vous a probablement déjà visité. Elle effraie les débutants, mais en réalité, c'est une porte d'entrée vers le monde de l'assertion de type — l'un des mécanismes les plus puissants et en même temps les plus sournois du langage.
Dans cet article, nous ne nous contenterons pas d'analyser l'erreur. Nous comprendrons pourquoi Go est si strict, comment convertir correctement interface{} en chaîne et en d'autres types, et comment ne pas tomber dans le piège du panic. Prêts ? C'est parti.
Qu'est-ce que interface{} et pourquoi est-ce compliqué ?
\nEn Go, interface{} (interface vide) est un type qui peut stocker une valeur de n'importe quel type. Cela semble magique, mais cela a un prix : Go ne permet pas de simplement prendre et assigner une valeur d'une variable interface{} à un type spécifique. Le langage exige une confirmation explicite : « Hé, je sais exactement ce qu'il y a à l'intérieur, c'est une chaîne, autorise-moi à la récupérer ».
C'est cette confirmation qui s'appelle assertion de type (type assertion). Sans elle, le compilateur affiche cette fameuse erreur :
\nvar data interface{} = "hello"\n// Erreur :\nstr := data // cannot use data (type interface{}) as type string\n\nPourquoi ? Parce que data est une boîte noire. Le compilateur ne sait pas ce qu'il y a dedans. Cela pourrait être une chaîne, un nombre, ou même une structure. La sécurité avant tout.
Assertion de type : sauveur ou source de panique ?
\nL'assertion de type est une syntaxe qui permet de « vérifier » et « extraire » la valeur d'un interface{}. Elle ressemble à ceci :
str := data.(string)\n\nMais il y a un détail : si data n'est pas une chaîne, votre programme plantera avec une panique. C'est pourquoi les développeurs expérimentés utilisent la forme de vérification (comma ok idiom) :
str, ok := data.(string)\nif !ok {\n // Gérer l'erreur : ce n'est pas une chaîne\n fmt.Println("Erreur : les données ne sont pas une chaîne")\n return\n}\nfmt.Println(str)\n\nMaintenant, si data est un nombre, le programme ne plantera pas, mais signalera simplement une erreur. Utilisez toujours la forme de vérification si vous n'êtes pas sûr à 100 % du type.
Exemple concret : analyser du JSON avec interface{}
\nLe scénario le plus courant où notre erreur se produit est le travail avec du JSON. Lorsque vous analysez du JSON sans structure stricte, Go transforme tout en map[string]interface{}. Et c'est là que les choses deviennent intéressantes.
Supposons que nous ayons ce JSON :
\n{\n "name": "Alice",\n "age": 30\n}\n\nNous l'analysons :
\njsonStr := `{"name": "Alice", "age": 30}`\nvar result map[string]interface{}\njson.Unmarshal([]byte(jsonStr), &result)\n\n// On essaie d'obtenir name\nname := result["name"].(string) // Fonctionne, mais dangereux\nfmt.Println(name) // Alice\n\n// On essaie d'obtenir age en tant que chaîne — panique !\nage := result["age"].(string) // panic: interface conversion: interface {} is float64, not string\n\nPourquoi une panique ? Parce que les nombres en JSON sont par défaut analysés comme float64, et non comme une chaîne. Conclusion : ne faites jamais d'assertion de type sans vérification.
Le code correct :
\nif name, ok := result["name"].(string); ok {\n fmt.Println("Name:", name)\n}\nif age, ok := result["age"].(float64); ok {\n fmt.Println("Age:", int(age))\n}\n\n\nType Switch : quand il y a plusieurs types
\nParfois, vous ne savez pas quel type se trouve dans interface{}. Pour ces cas, Go propose le type switch — une construction qui vérifie toutes les possibilités :
var data interface{} = getSomeData()\n\nswitch v := data.(typ