Leçons du module (2/5)
Assertion de type
Une assertion de type extrait le type concret d'une valeur d'interface.
C'est utile lorsque vous avez un interface{} (ou une interface "haute") en main et que vous
vous devez le traiter comme son propre type spécifique pour accéder aux champs ou aux méthodes
non présent dans l'interface.
Syntaxe
var i interface{} = "ciao"
s := i.(string) // forma "panic": panic se non è string
s, ok := i.(string) // forma "comma ok": ok = false se non è stringDeux formes, deux sémantiques :
| Forme | Succès | Faillite |
|---|---|---|
v := i.(T) | v = valeur de type T | panique au moment de l'exécution |
v, ok := i.(T) | v=..., ok=true | v = valeur nulle de T, ok=false |
Formulaire "virgule ok" : le plus sûr
var i interface{} = 42
if s, ok := i.(string); ok {
fmt.Println("è stringa:", s)
} else {
fmt.Println("non è stringa, ignoro")
}ok vous permet de gérer le cas du « mauvais type » sans panique. C'est le
modèle idiomatique dans la grande majorité des cas.
Affirmation envers une interface
L'affirmation fonctionne non seulement vers des types concrets, mais aussi vers d'autres interfaces :
type Closer interface { Close() error }
func tryClose(x interface{}) {
if c, ok := x.(Closer); ok {
c.Close()
}
}Modèle très courant dans la bibliothèque standard : "si mon entrée est également
a io.Closer, j'appelle Close lorsque j'ai terminé".
Assertion sur les pointeurs par rapport aux valeurs
L'assertion doit correspondre EXACTEMENT au type dynamique :
type Cat struct{}
func (c *Cat) Meow() {}
var a interface{} = &Cat{}
c1, ok := a.(*Cat) // ok = true
c2, ok := a.(Cat) // ok = false: dentro c'è *Cat, non Cat*Cat et Cat sont des types distincts pour le système de types.
Quand utiliser le commutateur d'assertion ou de type
- un seul type possible, vérification de "détection de fonctionnalité" (par exemple, conversion vers une interface facultative) : assertion de type avec
comma ok. - 2+ types possibles, dispatch sur plusieurs branches : type switch (prochaine leçon).
Essayez-le vous-même
Utilisez le modèle virgule ok pour extraire une chaîne de i.
Afficher l'indice
Syntaxe : `v, ok := i.(T)`.
Solution disponible après 3 tentatives
Tapez l'assertion en int sans virgule ok (en supposant que i contienne un int).
Afficher l'indice
Sans `ok`, le type est supposé certain ; sinon panique.
Solution disponible après 3 tentatives
Que se passe-t-il avec `s := i.(string)` si i contient un int ?
var i interface{} = 42
s := i.(string)Récapitulatif
v := i.(T): panique si type dynamique ≠ T.v, ok := i.(T): modèle sécurisé, cochezok.- S'applique également à une autre interface (« détection de fonctionnalités »).
Tet*Tsont des types distincts pour l'assertion.- 1 type → assertion ; 2+ types → commutateur de type.