L'interface a emballé une valeur. L'assertion la rouvre.The interface wrapped a value. The assertion reopens it.
Deux numéros durant, la paire (type, valeur) nous a servis ou trahis sans qu'on y touche. On va maintenant l'ouvrir nous-mêmes. L'assertion de type, x.(T), prend une interface et en extrait le type concret qu'elle transporte — elle fait le chemin inverse de l'emballage. Le hic, c'est qu'on affirme un type : si l'interface n'en contient pas, l'assertion nue panique. D'où la forme à deux retours, v, ok := x.(T), qui ne panique jamais : elle pose une question au lieu d'asséner une certitude. C'est la version sûre, et la seule qu'on devrait écrire par défaut.For two issues, the (type, value) pair served or betrayed us without our touching it. Now we'll open it ourselves. The type assertion, x.(T), takes an interface and extracts the concrete type it carries — it walks the wrapping backwards. The catch is that you assert a type: if the interface holds another, the bare assertion panics. Hence the two-result form, v, ok := x.(T), which never panics: it asks a question instead of stating a certainty. It's the safe version, and the only one you should write by default.
var i any = "hello" // la paire : (string, "hello") s := i.(string) // "hello" — on ressort le type concret n := i.(int) // panic: interface conversion: // string is not int // l'assertion nue exige d'avoir RAISON sur le type — sinon, panic.
s, ok := i.(string) // "hello", true n, ok := i.(int) // 0, false — pas de panic, ok dit l'échec if ok { use(n) // on n'entre QUE si le type colle } // la forme à deux retours transforme une erreur fatale en branche.
Ranger un int dans une any remplit la paire ; l'assertion i.(int) la vide à nouveau dans un int concret. L'assertion n'est pas une conversion — elle ne transforme rien : elle vérifie que le type rangé est bien celui qu'on demande, et rend la valeur telle quelle.Storing an int in an any fills the pair; the assertion i.(int) empties it back into a concrete int. The assertion isn't a conversion — it transforms nothing: it checks the stored type is the one you ask for, and returns the value as is.
« Une interface, on ne la rouvre qu'avec le ok. » L'assertion nue est un pari sur le type ; perdu, il panique. La forme à deux retours en fait une branche. Tout le numéro déroule ce qu'on peut faire de la paire rouverte — router selon le type, en payer le coût — et quand il vaut mieux ne jamais l'avoir emballée."You reopen an interface only with the ok." The bare assertion is a bet on the type; lost, it panics. The two-result form turns it into a branch. The whole issue unrolls what you can do with the reopened pair — route on type, pay its cost — and when you'd have been better off never wrapping it.
T dans x.(T) n'est pas forcément un type concret : ça peut être une autre interface. x.(io.Reader) demande « la valeur cachée sait-elle Read ? » et, si oui, te rend une vue io.Reader dessus. C'est le mécanisme derrière des idiomes comme err.(interface{ Temporary() bool }) : on teste à l'exécution si la valeur satisfait un comportement, sans connaître son type. La paire ne rend pas que du concret — elle rend l'angle de vue qu'on lui demande, du moment qu'il est compatible.T in x.(T) needn't be a concrete type: it can be another interface. x.(io.Reader) asks 'does the hidden value know how to Read?' and, if so, hands you an io.Reader view of it. It's the mechanism behind idioms like err.(interface{ Temporary() bool }): you test at runtime whether the value satisfies a behaviour, without knowing its type. The pair returns not only concretes — it returns the angle you ask for, as long as it's compatible.