Direct naar de hoofdinhoud
Module 6 · Les 3 van 528/50 in de cursus~10 min
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

Go
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 binnen switch.
  • v := ... bindt de waarde met het huidige casetype: binnen case int heeft v type int.
  • default vangt alle andere typen; daar heeft v het type van de originele interface.
  • case nil komt overeen met de interface met een dynamisch type nul.

"Nameloze" zaak

Als u de getypte waarde niet nodig heeft, kunt u v weglaten:

Go
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

Go
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

Go
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

Oefening#go.m6.l3.e1
Pogingen: 0Laden…

Implementeer de tekenreeks write(i interface{}) die 'int', 'string' of 'altro' retourneert, afhankelijk van het dynamische type.

Editor laden…
Toon hint

Syntaxis: `schakelaar i.(type) { case T: ... standaard: ... }`.

Oplossing beschikbaar na 3 pogingen

Oefening#go.m6.l3.e2
Pogingen: 0Laden…

Schrijf printVal(i interface{}) dat v := i.(type) gebruikt en print met %d voor int, %s voor string.

Editor laden…
Toon hint

Binnen `case int` heeft v het type int (je kunt het doorgeven aan Printf).

Oplossing beschikbaar na 3 pogingen

Quiz#go.m6.l3.e3
Klaar

Welke syntaxis start een typewissel?

Go
switch ??? {
  case int: ...
}
Antwoordmogelijkheden

Samenvatten

  • switch v := i.(type) { case T: ... }: discrimineert op het dynamische type.
  • Binnen een zaak van één type heeft v het type van de zaak.
  • case T1, T2: v behoudt het type van de originele interface.
  • default voor niet-afgehandelde zaken; case nil voor de nul-interface.
  • Geen fallthrough in typeschakelaars.
  • 1 type → typeverklaring; 2+ typen → typeschakelaar.