Salt la conținutul principal
Modulul 6 · Lecția 2 din 527/50 în curs~10 min
Lecții din modul (2/5)

Tip afirmație

O aserțiune de tip extrage tipul concret dintr-o valoare de interfață. Aveți nevoie de el atunci când aveți o interface{} (sau o interfață „înaltă”) în mână și trebuie să o tratezi ca tipul său specific pentru a accesa câmpuri sau metode care nu sunt prezente pe interfață.

Sintaxă

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

Două forme, două semantice:

FormularSuccesEșec
v := i.(T)v = valoare de tip Tpanica la runtime
v, ok := i.(T)v=..., ok=truev = valoarea zero a lui T, ok=false

Forma „virgulă ok”: cea mai sigură

Go
var i interface{} = 42

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

ok vă permite să gestionați cazul de „tip greșit” fără panică. Este model idiomatic în marea majoritate a cazurilor.

Afirmație la o interfață

Afirmația nu funcționează doar pe tipuri concrete, ci și pe altele interfete:

Go
type Closer interface { Close() error }

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

Un model foarte comun în biblioteca standard: „dacă intrarea mea este, de asemenea un io.Closer, apelați Închidere la sfârșit”.

Aserțiune despre indicatori vs valori

Afirmația trebuie să se potrivească EXACT tipului dinamic:

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 sunt tipuri distincte pentru sistemul de tipuri.

Când să folosiți aserțiunea vs comutatorul de tip

  • Doar 1 tip posibil, verificare „detectare caracteristică” (de exemplu, difuzare către o interfață opțională): aserțiune de tip cu comma ok.
  • 2+ tipuri posibile, expediere peste mai multe ramuri: comutator de tip (lecția următoare).

Încearcă

Exercițiu#go.m6.l2.e1
Încercări: 0Se încarcă…

Utilizați modelul virgulă ok pentru a extrage un șir din i.

Se încarcă editorul...
Afișează indiciu

Sintaxă: `v, ok := i.(T)`.

Soluție disponibilă după 3 încercări

Exercițiu#go.m6.l2.e2
Încercări: 0Se încarcă…

Tastați aserțiune la int fără virgulă ok (presupunem că i conține un int).

Se încarcă editorul...
Afișează indiciu

Fără `ok` presupui că tipul este sigur; altfel panica.

Soluție disponibilă după 3 încercări

Quiz#go.m6.l2.e3
Gata

Ce se întâmplă cu `s := i.(string)` dacă i conține un int?

Go
var i interface{} = 42
s := i.(string)
Opțiuni de răspuns

Recapitulare

  • v := i.(T): panică dacă tipul dinamic ≠ T.
  • v, ok := i.(T): model sigur, bifați ok.
  • Funcționează și împotriva unei alte interfețe („feature detect”).
  • T și *T sunt tipuri distincte pentru afirmație.
  • 1 tip → aserțiune; 2+ tipuri → comutator de tip.