Vai al contenuto
eLearner.app
Modulo 6 · Lezione 2 di 527/50 nel corso~10 min
Lezioni del modulo (2/5)

Type assertion

Una type assertion estrae il tipo concreto da un valore di interfaccia. Serve quando hai in mano un interface{} (o un'interfaccia "alta") e ti serve trattarlo come il suo tipo specifico per accedere a campi o metodi non presenti nell'interfaccia.

Sintassi

Go
var i interface{} = "ciao"

s := i.(string)           // forma "panic": panic se non è string
s, ok := i.(string)       // forma "comma ok": ok = false se non è string

Due forme, due semantiche:

FormaSuccessoFallimento
v := i.(T)v = valore di tipo Tpanic a runtime
v, ok := i.(T)v=..., ok=truev = zero value di T, ok=false

Forma "comma ok": la più sicura

Go
var i interface{} = 42

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

ok ti permette di gestire il caso "tipo sbagliato" senza panic. È il pattern idiomatico nella stragrande maggioranza dei casi.

Assertion verso un'interfaccia

L'asserzione non funziona solo verso tipi concreti, ma anche verso altre interfacce:

Go
type Closer interface { Close() error }

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

Pattern molto comune nella standard library: "se il mio input è anche un io.Closer, chiamo Close al termine".

Assertion su puntatori vs valori

L'asserzione deve corrispondere ESATTAMENTE al tipo dinamico:

Go
type Cat struct{}
func (c *Cat) Meow() {}

var a interface{} = &Cat{}

c1, ok := a.(*Cat)   // ok = true
c2, ok := a.(Cat)    // ok = false: dentro c'è *Cat, non Cat

*Cat e Cat sono tipi distinti per il type system.

Quando usare assertion vs type switch

  • 1 solo tipo possibile, controllo "feature-detect" (es. cast a un'interfaccia opzionale): type assertion con comma ok.
  • 2+ tipi possibili, dispatch su più rami: type switch (prossima lezione).

Prova tu

Esercizio#go.m6.l2.e1
Tentativi: 0Caricamento…

Usa il pattern comma ok per estrarre una string da i.

Caricamento editor…
Mostra suggerimento

Sintassi: `v, ok := i.(T)`.

Soluzione disponibile dopo 3 tentativi

Esercizio#go.m6.l2.e2
Tentativi: 0Caricamento…

Type assertion verso int senza comma ok (assumi che i contenga un int).

Caricamento editor…
Mostra suggerimento

Senza `ok` si suppone che il tipo sia certo; altrimenti panic.

Soluzione disponibile dopo 3 tentativi

Quiz#go.m6.l2.e3
Pronto

Cosa succede con `s := i.(string)` se i contiene un int?

Go
var i interface{} = 42
s := i.(string)
Opzioni di risposta

Recap

  • v := i.(T): panic se il tipo dinamico ≠ T.
  • v, ok := i.(T): pattern sicuro, controlla ok.
  • Vale anche verso un'altra interfaccia ("feature detect").
  • T e *T sono tipi distinti per l'assertion.
  • 1 tipo → assertion; 2+ tipi → type switch.