Lektionen des Moduls (2/5)
Type Assertion
Eine Typzusicherung extrahiert den konkreten Typ aus einem Schnittstellenwert.
Sie benötigen es, wenn Sie eine interface{}-Schnittstelle (oder eine „hohe“ Schnittstelle) haben
Hand und müssen es als seinen spezifischen Typ behandeln, um auf Felder oder zuzugreifen
Methoden, die auf der Schnittstelle nicht vorhanden sind.
Syntax
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 stringZwei Formen, zwei Semantiken:
| Formular | Erfolg | Fehler |
|---|---|---|
v := i.(T) | v = Wert vom Typ T | Panik zur Laufzeit |
v, ok := i.(T) | v=..., ok=true | v = Nullwert von T, ok=false |
„Komma ok“-Form: die sicherste
var i interface{} = 42
if s, ok := i.(string); ok {
fmt.Println("è stringa:", s)
} else {
fmt.Println("non è stringa, ignoro")
}Mit ok können Sie den Fall „falscher Typ“ ohne Panik bearbeiten. Es ist das
In den allermeisten Fällen handelt es sich um ein idiomatisches Muster.
Behauptung an eine Schnittstelle
Die Behauptung funktioniert nicht nur bei konkreten Typen, sondern auch bei anderen Schnittstellen:
type Closer interface { Close() error }
func tryClose(x interface{}) {
if c, ok := x.(Closer); ok {
c.Close()
}
}Ein sehr häufiges Muster in der Standardbibliothek: „Wenn meine Eingabe auch so ist.“
ein io.Closer, am Ende Close aufrufen.
Aussage zu Zeigern vs. Werten
Die Behauptung muss GENAU mit dem dynamischen Typ übereinstimmen:
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 und Cat sind unterschiedliche Typen für das Typsystem.
Wann sollte der Assertion-Vs-Typ-Schalter verwendet werden?
- Nur 1 möglicher Typ, „Feature-Detect“-Prüfung (z. B. Umwandlung in eine optionale Schnittstelle): Typzusicherung mit
comma ok. - 2+ mögliche Typen, Versand über mehrere Zweige: Typwechsel (nächste Lektion).
Probieren Sie es aus
Verwenden Sie das Komma-OK-Muster, um eine Zeichenfolge aus i zu extrahieren.
Hinweis anzeigen
Syntax: `v, ok := i.(T)`.
Lösung nach 3 Versuchen verfügbar
Geben Sie „assertion“ in int ohne Komma ein, ok (angenommen, i enthält ein int).
Hinweis anzeigen
Ohne `ok` gehen Sie davon aus, dass der Typ sicher ist; sonst Panik.
Lösung nach 3 Versuchen verfügbar
Was passiert mit `s := i.(string)`, wenn ich ein int enthält?
var i interface{} = 42
s := i.(string)Zusammenfassung
v := i.(T): Panik, wenn der dynamische Typ ≠ T.v, ok := i.(T): sicheres Muster, überprüfen Sieok.- Funktioniert auch gegen eine andere Schnittstelle ("Feature Detect").
Tund*Tsind unterschiedliche Typen für die Behauptung.- 1 Typ → Behauptung; 2+ Typen → Typschalter.