Passer au contenu principal
eLearner.app
Module 6 · Leçon 2 sur 527/50 dans le cours~10 min
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

Go
var i interface{} = "ciao"

s := i.(string)           // forma "panic": panic se non è string
s, ok := i.(string)       // forma "comma ok": ok = false se non è string

Deux formes, deux sémantiques :

FormeSuccèsFaillite
v := i.(T)v = valeur de type Tpanique au moment de l'exécution
v, ok := i.(T)v=..., ok=truev = valeur nulle de T, ok=false

Formulaire "virgule ok" : le plus sûr

Go
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 :

Go
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 :

Go
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

Exercice#go.m6.l2.e1
Tentatives : 0Chargement…

Utilisez le modèle virgule ok pour extraire une chaîne de i.

Chargement de l'éditeur…
Afficher l'indice

Syntaxe : `v, ok := i.(T)`.

Solution disponible après 3 tentatives

Exercice#go.m6.l2.e2
Tentatives : 0Chargement…

Tapez l'assertion en int sans virgule ok (en supposant que i contienne un int).

Chargement de l'éditeur…
Afficher l'indice

Sans `ok`, le type est supposé certain ; sinon panique.

Solution disponible après 3 tentatives

Quiz#go.m6.l2.e3
Prêt

Que se passe-t-il avec `s := i.(string)` si i contient un int ?

Go
var i interface{} = 42
s := i.(string)
Options de réponse

Récapitulatif

  • v := i.(T) : panique si type dynamique ≠ T.
  • v, ok := i.(T) : modèle sécurisé, cochez ok.
  • S'applique également à une autre interface (« détection de fonctionnalités »).
  • T et *T sont des types distincts pour l'assertion.
  • 1 type → assertion ; 2+ types → commutateur de type.