Que Son Los Punteros En Go: Guía Esencial
Imagina que estás programando en Go y una función no modifica tu variable como esperas.
Pasa por valor, siempre copia. Ahí es donde brillan los punteros en Go.
Que Son Los Punteros En Go: Guía Esencial te lleva de cero a experto.
Vamos a desmenuzarlo paso a paso, con ejemplos reales.
¿Qué son exactamente los punteros?
Los punteros en Go son variables que guardan la dirección de memoria de otra variable.
No almacenan el valor, solo dónde encontrarlo.
💡 Si estás explorando lógica booleana o programación, descubre cómo construir tablas de valores lógicos para simplificar expresiones complejas y tomar decisiones más rápidas en tus proyectos.
¿Suena abstracto? Piensa en un puntero como una flecha que apunta a tu dato.
Go los usa para pasar por referencia, modificando el original.
Sin punteros, funciones copian todo.
Eficiencia cero en structs grandes.
Punteros evitan copias innecesarias.
Útiles en listas enlazadas o árboles.
Cómo crear un puntero en Go
💡 Si buscas potenciar tu carrera en tech y multiplicar ingresos, no te pierdas cómo dominar inglés y programación abre puertas a sueldos top – ¡el combo perfecto para destacar!
Declarar un puntero es simple: usa * antes del tipo.
var p *int crea un puntero a entero.
Go ofrece tres formas:
- Declaración explícita:
var p *int. - Función
new():p := new(int). - Dirección con
&:p := &miVariable.
Veamos código.
package main
💡 Si estás evaluando migrar tus operaciones a la nube, descubre [los pros y contras del cloud computing](/ventajas-y-desventajas-de-la-nube/) para tomar una decisión estratégica y evitar sorpresas inesperadas.
import "fmt"
func main() {
v := 19
var p1 *int
p2 := new(int)
p3 := &v
fmt.Printf("p1: %T\n", p1) // *int
fmt.Printf("p2: %T\n", p2) // *int
fmt.Printf("p3: %T\n", p3) // *int
}
Todos son punteros a int.
new(int) asigna memoria y devuelve puntero a cero.
¿Pregunta común? ¿nil es válido? Sí, punteros no inicializados son nil.
Cuidado: desreferenciar nil causa pánico.
💡 Si estás explorando el mundo de la estadística y quieres dominar los fundamentos, descubre esta guía exhaustiva de distribuciones probabilísticas que desglosa cada tipo con ejemplos prácticos y claros.
El operador & : obtener la dirección
&variable da la dirección de memoria.
Es como pedirle a Go: “¿Dónde vives?”.
Ejemplo rápido:
package main
import "fmt"
💡 Si estás configurando un entorno fresco en VSCode y odias instalar extensiones una por una, descubre [este script para automatizar la instalación de plugins esenciales](/script-instalar-extensiones-vscode/) y acelera tu workflow en minutos.
func main() {
v := 19
fmt.Println("Valor:", v)
fmt.Println("Dirección:", &v) // Algo como 0x10414020
}
La salida muestra un hex.
Única por ejecución, cambia siempre.
¿Por qué importa? Para pasar punteros a funciones.
Sin &, copias el valor.
Desreferenciar con el operador *
*puntero accede al valor en esa dirección.
Es “seguir la flecha”.
Código práctico:
package main
import "fmt"
func main() {
v := 19
p := &v
fmt.Println("Valor vía puntero:", *p) // 19
*p = 20
fmt.Println("Nuevo valor:", v) // 20, ¡modificado!
}
¡Magia! Cambias *p y v se actualiza.
Desreferenciación es clave.
¿Error típico? Olvidar * al asignar.
Go te avisa en compile-time.
Punteros en funciones: el verdadero poder
Go pasa por valor por defecto.
Función recibe copia, original intacto.
Problema clásico:
package main
import "fmt"
func Increase(v int) {
v++
}
func main() {
var v int = 19
Increase(v)
fmt.Println("v:", v) // 19, no cambió
}
Frustrante, ¿verdad?
Punteros lo arreglan: pasa &v.
Versión con puntero:
package main
import "fmt"
func Increase(p *int) {
*p++
}
func main() {
var v int = 19
Increase(&v)
fmt.Println("v:", v) // 20, ¡sí!
}
Función recibe *int, usa *p++.
Modifica original.
¿Cuándo usar? En métodos de structs grandes.
Ahorra memoria.
Tabla comparativa:
| Aspecto | Por Valor | Por Puntero |
|---|---|---|
| Copia datos | Sí, siempre | No, solo dir. |
| Modifica orig. | No | Sí |
| Eficiencia | Baja en structs | Alta |
| Seguridad | Alta (inmutable) | Cuidado con nil |
Punteros y tipos: structs y slices
Punteros brillan con structs.
Copia completa sin ellos.
Ejemplo struct:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func Birthday(p *Person) {
p.Age++
}
func main() {
p := &Person{Name: "Ana", Age: 30}
Birthday(p)
fmt.Println(p.Name, p.Age) // Ana 31
}
Sin puntero, Birthday copiaría todo.
Lento para structs complejos.
Slices ya son referencias, pero punteros a slices útiles.
Maps iguales.
¿Duda? Slices son “fat pointers”: puntero + longitud + capacidad.
Errores comunes y mejores prácticas
Pánico por nil: Siempre chequea if p != nil.
Go no tiene punteros nulos seguros automáticos.
Código seguro:
func SafeIncrement(p *int) {
if p != nil {
*p++
}
}
Ciclos de referencia: Raros en Go por GC.
No te preocupes mucho.
Regla oro: Usa punteros para modificar, valores para leer.
Convención: métodos con receiver puntero para mutación.
Humor: Punteros no muerden, pero nil sí.
Prueba en playground.go.
¿Slices grandes? Pasa puntero al slice entero: func(p *[]int).
Punteros avanzados: métodos y interfaces
En receivers: func (p *Person) Walk() {}.
Permite mutación dentro.
Interfaces aceptan punteros.
io.Writer funciona con *bytes.Buffer.
Ejemplo método:
func (p *Person) Birthday() {
p.Age++
}
p := &Person{Age: 30}
p.Birthday() // OK
¿Valor receiver? Copia implícita, no muta.
Elige sabiamente.
Casos reales: cuándo evitar punteros
No abuses. Valores simples (int, string) cópialos.
Punteros para:
- Árboles, grafos.
- Pools de objetos.
- APIs grandes.
En concurrencia: canales > punteros compartidos.
Race conditions matan.
Pregunta: ¿Necesitas puntero aquí?
Pregúntate: “¿Modificaré?”.
Ejemplos del mundo real
Lista enlazada simple:
type Node struct {
Value int
Next *Node
}
func AddFront(head **Node, value int) {
newNode := &Node{Value: value}
newNode.Next = *head
*head = newNode
}
Pasa **Node para modificar head.
¡Funciona!
En web servers: punteros a structs de request.
Eficiencia pura.
Conclusión: domina los punteros
Punteros en Go transforman tu código.
De copias lentas a referencias rápidas.
Practica: refactoriza funciones mutantes.
Go te recompensa con velocidad.
¿Listo para más? Explora unsafe package, pero con cuidado.
Que Son Los Punteros En Go ya es tuyo.
Sigue codificando, amigo.