new() y cuándo usar punteros
Asignación con new y patrones habituales de punteros
new() y cuándo usar punteros es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.
El elemento integrado new()
new(T) asigna un valor T inicializado a cero y devuelve un *T. Para las estructuras, equivale a &T{}:
package main
import "fmt"
func main() {
p := new(int)
fmt.Println(*p) // 0
*p = 42
fmt.Println(*p) // 42
type Point struct{ X, Y int }
pt := new(Point)
fmt.Println(*pt) // {0 0}
}new frente a &T{}
Para las estructuras, &T{} es más idiomático y permite inicializar campos. new se utiliza rara vez en el Go moderno:
package main
import "fmt"
type Config struct{ Port int; Host string }
func main() {
a := new(Config) // zeroed
b := &Config{Port: 8080} // initialized
fmt.Println(a, b)
}Cuándo devolver un puntero
Devuelva un puntero desde un constructor cuando:
- La estructura tenga estado y el código que la llama deba compartir la misma instancia
- La estructura tenga métodos con receptores por puntero (necesarios para satisfacer interfaces)
- La estructura sea grande y las copias resulten costosas
Cuándo devolver un valor
Devuelva un valor cuando:
- El tipo sea pequeño (tenga unos pocos campos)
- Se trate de una configuración inmutable
- Quiera dejar claro que el código que llama recibe copias independientes
Ejemplo: time.Time se devuelve por valor a pesar de tener muchos métodos.
Punteros en slices y mapas
Almacenar punteros en colecciones permite compartir las modificaciones:
package main
import "fmt"
type User struct{ Name string; Score int }
func main() {
users := []*User{{"Alice", 0}, {"Bob", 0}}
users[0].Score = 100
fmt.Println(users[0]) // &{Alice 100}
}Punteros a tipos primitivos para representar opcionalidad
Un campo *int o *string puede ser nil para indicar «no establecido», lo que resulta útil con JSON y omitempty o con columnas opcionales de una base de datos:
package main
import "fmt"
type Profile struct {
Name string
Age *int // nil means not provided
}
func main() {
p := Profile{Name: "Alice"}
fmt.Println(p.Age == nil) // true
age := 30
p.Age = &age
fmt.Println(*p.Age) // 30
}Evitar la proliferación de punteros
El uso excesivo de punteros aumenta la presión sobre el recolector de basura y reduce la localidad de caché. Compare el rendimiento antes de cambiar tipos por valor a punteros únicamente por motivos de rendimiento.
make frente a new
make inicializa slices, mapas y canales (necesitan una configuración interna). new reserva memoria inicializada a cero para cualquier tipo y devuelve un puntero. Tienen finalidades diferentes:
package main
import "fmt"
func main() {
s := make([]int, 5) // usable slice
m := make(map[string]int) // usable map
p := new(int) // *int pointing to 0
fmt.Println(s, m, *p)
}Patrón de puntero inmutable
Devuelva *T, pero documente que es inmutable; los consumidores no deben modificarlo. Esto es habitual en objetos de configuración compartidos entre goroutines.
Resumen sobre la seguridad de los punteros
Reglas para utilizar punteros de forma segura:
- Compruebe siempre nil antes de desreferenciar
- No almacene punteros a variables de la pila durante más tiempo que la vida útil de la variable (el análisis de escape de Go se encarga de esto)
- No convierta nunca a unsafe.Pointer salvo que sea absolutamente necesario
- Deje que el compilador gestione la pila y el heap
Comprobación rápida
¿Qué devuelve new(int)?
Repaso: new y los punteros
Conclusiones principales:
new(T)devuelve*Tinicializado a cero; se utiliza rara vez, por lo que debe preferir&T{}- Devuelva valores cuando sean pequeños o inmutables; use punteros cuando haya estado o sean grandes
- Los campos
*Tpermiten representar la ausencia mediante nil - No utilice punteros en exceso; el recolector de basura tiene un coste
Propuesta de práctica
Cree una estructura Settings con un campo *int para MaxConnections. Escriba una función que acepte *Settings y establezca un valor predeterminado solo cuando el campo sea nil.
Preguntas frecuentes
¿La lección «new() y cuándo usar punteros» es gratis?
Sí — el texto completo de «new() y cuándo usar punteros» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.
¿Qué aprenderé en «new() y cuándo usar punteros»?
Asignación con new y patrones habituales de punteros Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Go Academy?
No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «new() y cuándo usar punteros»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Go Academy?
Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- ¿Qué son los punteros?
- Punteros y funciones
- Receivers por puntero en métodos
- new() y cuándo usar punteros