Saltar al contenido principal
eLearner.app
Módulo 6 · Lección 2 de 527/50 en el curso~10 min
Lecciones del módulo (2/5)

Aserción de tipo

Una aserción de tipo extrae el tipo concreto de un valor de interfaz. Lo necesita cuando tiene un interface{} (o una interfaz "alta") en mano y es necesario tratarlo como su tipo específico para acceder a campos o métodos no presentes en la interfaz.

Sintaxis

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

Dos formas, dos semánticas:

FormularioÉxitoFracaso
CÓDIGOPH0v = valor de tipo Tpánico en tiempo de ejecución
CÓDIGOPH2CÓDIGOPH3, CÓDIGOPH4v = valor cero de T, ok=false

Formulario "Coma ok": el más seguro

Go
var i interface{} = 42

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

ok le permite manejar el caso de "tipo incorrecto" sin pánico. es el patrón idiomático en la gran mayoría de los casos.

Aserción a una interfaz

La afirmación no funciona sólo en tipos concretos, sino también en otros. interfaces:

Go
type Closer interface { Close() error }

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

Un patrón muy común en la biblioteca estándar: "si mi entrada también es un io.Closer, llame a Cerrar al final".

Afirmación sobre punteros versus valores

La aserción debe coincidir EXACTAMENTE con el tipo dinámico:

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 y Cat son tipos distintos para el sistema de tipos.

Cuándo usar aserción versus cambio de tipo

  • Solo 1 tipo posible, verificación de "detección de características" (por ejemplo, conversión a una interfaz opcional): afirmación de tipo con comma ok.
  • 2+ tipos posibles, envío a través de múltiples ramas: tipo switch (próxima lección).

Pruébalo

Ejercicio#go.m6.l2.e1
Intentos: 0Cargando...

Utilice el patrón de coma ok para extraer una cadena de i.

Cargando editor...
Mostrar pista

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

Solución disponible después de 3 intentos

Ejercicio#go.m6.l2.e2
Intentos: 0Cargando...

Escriba aserción en int sin coma (supongamos que i contiene un int).

Cargando editor...
Mostrar pista

Sin `ok` se supone que el tipo es seguro; de lo contrario, pánico.

Solución disponible después de 3 intentos

Cuestionario#go.m6.l2.e3
Listo

¿Qué sucede con `s := i.(string)` si contiene un int?

Go
var i interface{} = 42
s := i.(string)
Opciones de respuesta

Resumen

  • v := i.(T): pánico si el tipo dinámico ≠ T.
  • v, ok := i.(T): patrón seguro, consultar ok.
  • Funciona también contra otra interfaz ("detección de funciones").
  • T y *T son tipos distintos de afirmación.
  • 1 tipo → afirmación; 2+ tipos → interruptor de tipo.