Modulelessen (2/5)
Typ bewering
Een type-verklaring extraheert het betontype uit een interfacewaarde.
Je hebt het nodig als je een interface{} (of een "hoge" interface) hebt
hand en moet het als zijn specifiek type behandelen om toegang te krijgen tot velden of
methoden die niet aanwezig zijn op de interface.
Syntaxis
var i interface{} = "ciao"
s := i.(string) // "panic" form: panics if it's not a string
s, ok := i.(string) // "comma ok" form: ok = false if it's not a stringTwee vormen, twee semantiek:
| Vorm | Succes | Mislukking |
|---|---|---|
v := i.(T) | v = waarde van type T | paniek tijdens runtime |
v, ok := i.(T) | v=..., ok=true | v = nulwaarde van T, ok=false |
"Comma ok"-vorm: de veiligste
var i interface{} = 42
if s, ok := i.(string); ok {
fmt.Println("è stringa:", s)
} else {
fmt.Println("non è stringa, ignoro")
}Met ok kunt u zonder paniek de zaak van het 'verkeerde type' afhandelen. Het is de
idiomatisch patroon in de overgrote meerderheid van de gevallen.
Bewering aan een interface
De bewering werkt niet alleen op betontypen, maar ook op andere interfaces:
type Closer interface { Close() error }
func tryClose(x interface{}) {
if c, ok := x.(Closer); ok {
c.Close()
}
}Een veel voorkomend patroon in de standaardbibliotheek: "als mijn invoer ook
een io.Closer, bel Sluiten aan het einde".
Bewering over aanwijzingen versus waarden
De bewering moet EXACT overeenkomen met het dynamische type:
type Cat struct{}
func (c *Cat) Meow() {}
var a interface{} = &Cat{}
c1, ok := a.(*Cat) // ok = true
c2, ok := a.(Cat) // ok = false: it holds *Cat, not Cat*Cat en Cat zijn verschillende typen voor het typesysteem.
Wanneer moet u assertie versus type-schakelaar gebruiken?
- Slechts 1 mogelijk type, "feature-detect"-controle (bijvoorbeeld casten naar een optionele interface): typeverklaring met
comma ok. - 2+ mogelijke typen, verzending over meerdere filialen: typewissel (volgende les).
Probeer het
Gebruik het komma ok-patroon om een string uit i te extraheren.
Toon hint
Syntaxis: `v, ok := i.(T)`.
Oplossing beschikbaar na 3 pogingen
Typ assertion to int zonder komma ok (neem aan dat i een int bevat).
Toon hint
Zonder 'ok' ga je ervan uit dat het type zeker is; anders paniek.
Oplossing beschikbaar na 3 pogingen
Wat gebeurt er met `s := i.(string)` als i een int bevat?
var i interface{} = 42
s := i.(string)Samenvatten
v := i.(T): paniek als het dynamische type ≠ T.v, ok := i.(T): veilig patroon, controleerok.- Werkt ook tegen een andere interface ("feature detect").
Ten*Tzijn verschillende typen voor de bewering.- 1 type → bewering; 2+ typen → typeschakelaar.