Modulelessen (3/5)
Type schakelaar
Een typeschakelaar maakt onderscheid tussen meerdere mogelijke typen an
interfacewaarde. Het is de generalisatie van comma ok als die er wel is
meer dan één geval.
Syntaxis
func describe(i interface{}) string {
switch v := i.(type) {
case int:
return fmt.Sprintf("int %d", v)
case string:
return fmt.Sprintf("string %q", v)
case nil:
return "nil"
default:
return fmt.Sprintf("altro tipo: %T", v)
}
}i.(type)is een speciale syntaxis, ALLEEN geldig binnenswitch.v := ...bindt de waarde met het huidige casetype: binnencase intheeftvtypeint.defaultvangt alle andere typen; daar heeftvhet type van de originele interface.case nilkomt overeen met de interface met een dynamisch type nul.
"Nameloze" zaak
Als u de getypte waarde niet nodig heeft, kunt u v weglaten:
switch i.(type) {
case int:
// you know it's an int, but you don't have a variable of that type
case string:
// ...
}Een formulier dat wordt gebruikt als u alleen het type wilt onderscheiden, niet werken op de waarde.
Meerdere soorten in dezelfde koffer
switch v := i.(type) {
case int, int64:
// here v is still interface{}: the "common" type is just the interface
fmt.Println("numero intero:", v)
case string:
// here v is string
fmt.Println("stringa:", v)
}Typisch gebruiksscenario: geformatteerd afdrukken
func print(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("%d\n", v)
case string:
fmt.Printf("%s\n", v)
case fmt.Stringer:
fmt.Println(v.String())
default:
fmt.Printf("%v\n", v)
}
}fmt.Println gebruikt zelf intern een typeschakelaar om de
standaard formaten.
Type schakelaar versus reflectie
Voor een paar bekende typen → type schakelaar (snel, leesbaar).
Voor dynamische inspectie van onbekende typen → het reflect pakket (meer
krachtig maar langzamer en uitgebreider).
Probeer het
Implementeer de tekenreeks write(i interface{}) die 'int', 'string' of 'altro' retourneert, afhankelijk van het dynamische type.
Toon hint
Syntaxis: `schakelaar i.(type) { case T: ... standaard: ... }`.
Oplossing beschikbaar na 3 pogingen
Schrijf printVal(i interface{}) dat v := i.(type) gebruikt en print met %d voor int, %s voor string.
Toon hint
Binnen `case int` heeft v het type int (je kunt het doorgeven aan Printf).
Oplossing beschikbaar na 3 pogingen
Welke syntaxis start een typewissel?
switch ??? {
case int: ...
}Samenvatten
switch v := i.(type) { case T: ... }: discrimineert op het dynamische type.- Binnen een zaak van één type heeft
vhet type van de zaak. case T1, T2:vbehoudt het type van de originele interface.defaultvoor niet-afgehandelde zaken;case nilvoor de nul-interface.- Geen
fallthroughin typeschakelaars. - 1 type → typeverklaring; 2+ typen → typeschakelaar.