Historia de la cuestión:
Go fue diseñado como un lenguaje con semántica de valor explícita: casi todo se copia por valor al pasar, incluidas las estructuras (struct), pero no punteros ni cortes (slice). Esto simplificó el razonamiento y aumentó la seguridad, pero trajo una serie de "trampas".
Problema:
A menudo, los desarrolladores esperan que al pasar una estructura a una función, sus cambios sean visibles hacia afuera. Pero se copia todo el contenido (¡incluidos los campos anidados — por valor!). Para cortes y mapas, hay un comportamiento diferente, donde se copia el "contenedor", pero no el "contenido".
Solución:
Pase estructuras grandes por puntero si se espera un cambio. Para los cortes, solo se copia el descriptor (longitud, capacidad, puntero), no el contenido; los cambios en el corte original (a través del índice) serán visibles externamente. Para struct, se copia todo:
type Point struct { X, Y int } func move(p Point) { p.X = 100 } func movePtr(p *Point) { p.X = 100 } func demo() { pt := Point{10, 10} move(pt) fmt.Println(pt.X) // 10 movePtr(&pt) fmt.Println(pt.X) // 100 }
Características clave:
Si se modifica la estructura dentro de la función, ¿se cambiará el original?
No, si la estructura se pasa por valor: los cambios son locales.
type User struct {Name string} func f(u User) {u.Name = "Ann"}
Si se modifica un elemento del corte dentro de la función, ¿se cambiará el original?
Sí. Los cortes son una "vista" de un array compartido. Al cambiar un elemento, cambias los datos originales.
func f(s []int) {s[0] = 99}
¿Qué pasará si se devuelve un corte creado dentro de la función?
La "cabeza" del corte se copia, pero el array subyacente sigue siendo accesible. Si no se guarda la referencia afuera, los datos pueden ser recolectados por el GC.
En la función, el manejo de la estructura User se realizó por valor — los cambios no llegaron de vuelta, los errores son difíciles de rastrear.
Ventajas:
Desventajas:
Las estructuras grandes se pasan claramente por puntero, y para los cortes siempre se comenta o se verifica el comportamiento. No hay confusión, todos esperan semántica de valor.
Ventajas:
Desventajas: