Menu
Coddy logo textTech

Interfaz vacía (any)

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy — lección 28 de 107.

La interfaz vacía es una interfaz con cero métodos. Dado que cada tipo en Go tiene al menos cero métodos, cada tipo satisface automáticamente la interfaz vacía. Esto la hace capaz de contener valores de cualquier tipo.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

A partir de Go 1.18, la palabra clave any se introdujo como un alias para interface{}. Son completamente intercambiables, pero any es más limpio de leer.

var value any = "Go is awesome"

La interfaz vacía es útil cuando necesitas manejar valores de tipos desconocidos o variables. Funciones como fmt.Println la utilizan para aceptar argumentos de cualquier tipo:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

Sin embargo, hay una compensación. Cuando un valor se almacena en una interfaz vacía, se pierde el acceso a su información de tipo específica.

No puedes llamar directamente a métodos ni acceder a campos sin extraer primero el tipo subyacente. Las próximas lecciones cubrirán cómo recuperar el tipo concreto de una interfaz vacía utilizando aserciones de tipo (type assertions) y conmutadores de tipo (type switches).

challenge icon

Desafío

Fácil

Vamos a construir un contenedor de almacenamiento flexible que pueda contener valores de cualquier tipo utilizando la interfaz vacía. Crearás una caja simple que demuestra cómo any te permite almacenar diferentes tipos en la misma estructura.

Organizarás tu código en dos archivos:

  • box.go: Define una estructura Box con un único campo Content de tipo any. Crea una función constructora NewBox que acepte un valor de cualquier tipo y devuelva un puntero a un Box que contenga ese valor. Añade un método Describe que devuelva una cadena que muestre lo que está almacenado en la caja.
  • main.go: Lee diferentes valores de la entrada, crea cajas que contengan un entero, una cadena y un booleano, luego imprime la descripción de cada caja para mostrar cómo el mismo tipo Box puede contener valores completamente diferentes.

Se proporcionarán las siguientes entradas:

  • Línea 1: Un valor entero
  • Línea 2: Un valor de cadena
  • Línea 3: Un valor booleano (true o false)

Tu método Describe debe devolver una cadena en este formato:

Box contains: [value]

Por ejemplo, dados 42, hello y true, tu salida debería ser:

Box contains: 42
Box contains: hello
Box contains: true

La idea clave aquí es que tu única estructura Box puede almacenar un entero, una cadena o un booleano, todo porque el tipo any acepta valores de cualquier tipo. Cada caja contiene algo diferente, pero todas son del mismo tipo Box.

Hoja de referencia

La interfaz vacía (interface{}) es una interfaz con cero métodos. Dado que cada tipo en Go tiene al menos cero métodos, cada tipo satisface automáticamente la interfaz vacía, lo que la hace capaz de contener valores de cualquier tipo.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

A partir de Go 1.18, se introdujo la palabra clave any como un alias para interface{}. Son completamente intercambiables, pero any es más limpio de leer:

var value any = "Go is awesome"

La interfaz vacía es útil para manejar valores de tipos desconocidos o variables. Las funciones pueden aceptar argumentos de cualquier tipo:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

Compromiso: Cuando un valor se almacena en una interfaz vacía, se pierde el acceso a la información de su tipo específico. No se pueden llamar directamente a los métodos ni acceder a los campos sin extraer primero el tipo subyacente mediante aserciones de tipo (type assertions) o selectores de tipo (type switches).

Pruébalo tú mismo

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Leer valor entero
	line1, _ := reader.ReadString('\n')
	intVal, _ := strconv.Atoi(strings.TrimSpace(line1))

	// Leer valor de cadena
	line2, _ := reader.ReadString('\n')
	strVal := strings.TrimSpace(line2)

	// Leer valor booleano
	line3, _ := reader.ReadString('\n')
	boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))

	// TODO: Crear cajas para cada valor usando NewBox
	// TODO: Imprimir la descripción de cada caja usando el método Describe

	// Usar las variables para evitar errores de compilación (eliminar estas líneas al implementar)
	_ = intVal
	_ = strVal
	_ = boolVal

	// Formato de salida de ejemplo:
	// fmt.Println(box.Describe())
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos