Menu
Coddy logo textTech

La función new()

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

Go proporciona una función incorporada llamada new() que asigna memoria para un tipo y devuelve un puntero a él. La memoria asignada se inicializa con el valor cero del tipo.

p := new(int)      // asigna memoria para un int
fmt.Println(*p)    // 0 (valor cero)
fmt.Println(p)     // 0xc000018030 (dirección de memoria)

La función new() toma un tipo como argumento y devuelve un puntero a un valor cero recién asignado de ese tipo. Esto es particularmente útil cuando necesitas un puntero pero no tienes una variable existente a la cual hacer referencia.

Con las estructuras, new() crea un puntero a una estructura con todos los campos establecidos en sus valores cero.

type Person struct {
    Name string
    Age  int
}

p := new(Person)
fmt.Println(p.Name)  // "" (cadena vacía)
fmt.Println(p.Age)   // 0

Tal vez te preguntes cuándo usar new() en comparación con el operador de dirección &. Ambos enfoques a continuación son equivalentes:

// Usando new()
p1 := new(Person)

// Usando el operador de dirección con un literal
p2 := &Person{}

La sintaxis &Person{} es más común en la práctica porque permite inicializar campos al mismo tiempo. Utiliza new() cuando desees específicamente una instancia con valores cero y prefieras una semántica de asignación de memoria explícita.

challenge icon

Desafío

Fácil

Vamos a construir un gestor de configuración que demuestre cómo new() asigna memoria e inicializa structs a sus valores cero. Verás cómo este enfoque difiere del uso del operador de dirección con un literal de struct.

Organizarás tu código en dos archivos:

  • config.go: Define un struct ServerConfig con los campos Host (string), Port (int), MaxConnections (int) y DebugMode (bool). Crea dos funciones:
    • NewServerConfig que utiliza new() para asignar un ServerConfig y devuelve el puntero directamente (con todos los valores cero)
    • ConfigureServer que recibe un puntero *ServerConfig junto con un string para el host y un entero para el puerto, y luego establece esos campos en la configuración a través del puntero
    También añade un método Display en *ServerConfig que devuelva un string formateado mostrando todos los valores de configuración.
  • main.go: Lee un host y un puerto de la entrada. Primero, crea una configuración usando NewServerConfig() y muéstrala para ver los valores cero. Luego usa ConfigureServer para establecer el host y el puerto, y muestra la configuración de nuevo para ver los valores actualizados.

Se proporcionarán las siguientes entradas:

  • Línea 1: Nombre del host (string)
  • Línea 2: Número de puerto (entero)

Tu método Display debe devolver un string en este formato exacto:

Host: [Host]
Port: [Port]
MaxConnections: [MaxConnections]
DebugMode: [DebugMode]

Imprime la salida de display dos veces: una antes de configurar (mostrando los valores cero) y otra después de configurar (mostrando el host y el puerto actualizados).

Por ejemplo, dados localhost y 8080, tu salida debería ser:

Host: 
Port: 0
MaxConnections: 0
DebugMode: false
Host: localhost
Port: 8080
MaxConnections: 0
DebugMode: false

Observa cómo la primera visualización muestra todos los valores cero (string vacío, 0, 0, false) porque new() inicializa todo a sus valores cero. Después de llamar a ConfigureServer, solo cambian el host y el puerto, mientras que los otros campos permanecen en sus valores cero.

Hoja de referencia

La función new() asigna memoria para un tipo y devuelve un puntero a él, inicializado al valor cero del tipo:

p := new(int)      // asigna memoria para un int
fmt.Println(*p)    // 0 (valor cero)
fmt.Println(p)     // 0xc000018030 (dirección de memoria)

Con structs, new() crea un puntero a un struct con todos los campos establecidos en sus valores cero:

type Person struct {
    Name string
    Age  int
}

p := new(Person)
fmt.Println(p.Name)  // "" (cadena vacía)
fmt.Println(p.Age)   // 0

El uso de new() frente al operador de dirección & - ambos son equivalentes:

// Usando new()
p1 := new(Person)

// Usando el operador de dirección con un literal
p2 := &Person{}

La sintaxis &Person{} es más común porque permite la inicialización de campos en el momento de la creación. Use new() cuando desee una instancia con valor cero con una semántica de asignación de memoria explícita.

Pruébalo tú mismo

package main

import (
	"fmt"
)

func main() {
	// Leer la entrada
	var host string
	var port int
	fmt.Scanln(&host)
	fmt.Scanln(&port)

	// TODO: Crear una configuración usando NewServerConfig() y mostrarla
	// Esto mostrará los valores cero

	// TODO: Usar ConfigureServer para establecer el host y el port

	// TODO: Mostrar la configuración de nuevo para ver los valores actualizados
}
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