Przejdź do głównej treści
eLearner.app
Moduł 6 · Lekcja 2 z 527/50 w kursie~10 min
Lekcje modułu (2/5)

Asercja typu

Afirmacja typu wyodrębnia konkretny typ z wartości interfejsu. Potrzebujesz go, gdy masz interface{} (lub „wysoki” interfejs). hand i należy go traktować jako specyficzny typ, aby uzyskać dostęp do pól lub metody, których nie ma w interfejsie.

Składnia

Go
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 string

Dwie formy, dwie semantyki:

FormularzSukcesPorażka
KODEF0v = wartość typu Tpanika w czasie wykonywania
KODEF2KODEF3, KODEF4v = wartość zerowa T, ok=false

Formularz „Przecinek ok”: najbezpieczniejszy

Go
var i interface{} = 42

if s, ok := i.(string); ok {
    fmt.Println("è stringa:", s)
} else {
    fmt.Println("non è stringa, ignoro")
}

ok pozwala bez paniki poradzić sobie z przypadkiem „złego typu”. To jest idiomatyczny wzór w zdecydowanej większości przypadków.

Asercja do interfejsu

Twierdzenie to nie działa tylko na konkretne typy, ale także na inne interfejsy:

Go
type Closer interface { Close() error }

func tryClose(x interface{}) {
    if c, ok := x.(Closer); ok {
        c.Close()
    }
}

Bardzo powszechny wzorzec w bibliotece standardowej: „jeśli moje dane wejściowe również to io.Closer, wywołaj Close na końcu”.

Asercja dotycząca wskaźników a wartości

Twierdzenie musi DOKŁADNIE pasować do typu dynamicznego:

Go
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 i Cat to różne typy systemu typów.

Kiedy używać asercji a przełącznika typu

  • Tylko 1 możliwy typ, sprawdzenie „wykrywania funkcji” (np. rzutowanie na opcjonalny interfejs): twierdzenie typu z comma ok.
  • 2+ możliwe typy, wysyłka przez wiele gałęzi: przełącznik typu (następna lekcja).

Spróbuj

Ćwiczenie#go.m6.l2.e1
Próby: 0Ładowanie...

Użyj wzorca przecinek ok, aby wyodrębnić ciąg z i.

Ładowanie edytora...
Pokaż wskazówkę

Składnia: `v, ok := i.(T)`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie#go.m6.l2.e2
Próby: 0Ładowanie...

Wpisz asercję na int bez przecinka ok (załóż, że i zawiera int).

Ładowanie edytora...
Pokaż wskazówkę

Bez `ok` zakładasz, że typ jest pewny; inaczej wpadnij w panikę.

Rozwiązanie dostępne po 3 próbach

Quiz#go.m6.l2.e3
Gotowe

Co się stanie z `s := i.(string)`, jeśli zawiera int?

Go
var i interface{} = 42
s := i.(string)
Opcje odpowiedzi

Podsumowanie

  • v := i.(T): panika, jeśli typ dynamiczny ≠ T.
  • v, ok := i.(T): bezpieczny wzór, sprawdź ok.
  • Działa także z innym interfejsem („wykrywanie funkcji”).
  • T i *T to różne typy asercji.
  • 1 typ → asercja; Ponad 2 typy → przełącznik typu.