En Go, la mayoría de los tipos de datos incorporados (por ejemplo, int, float, struct) son mutables si se declaran como variables, porque al pasarlas por valor se copia toda la estructura o valor. Pero hay un detalle: los 'slices', mapas (map), canales (channel) son tipos de referencia con su propia lógica interna de almacenamiento de datos.
Tipos básicos:
x := 10 y := x // Aquí se crea una copia del valor, x e y no están relacionados entre sí y = 20 // x permanecerá en 10
Slices:
a := []int{1,2,3} b := a // referencia a la misma "base" del arreglo b[0] = 100 // ahora a[0] == 100
Esto es importante si una función o método acepta una estructura o un slice, porque los cambios pueden afectar los datos originales o no, dependiendo del tipo de datos y el método de paso (por valor o por referencia).
Pregunta: "Si asignas un slice a otro, ¿obtienes una copia profunda o ambos apuntan a los mismos datos?"
Respuesta: Con la simple asignación de slices (b := a) — ambos apuntan al mismo arreglo base, pero tienen longitud y capacidad independientes. Los cambios a través de uno de los slices son visibles en el otro.
Ejemplo:
a := []int{1,2,3} b := a b[0] = 42 fmt.Println(a) // [42 2 3]
Para hacer una copia profunda, se usa copy:
c := make([]int, len(a)) copy(c, a) c[0] = 99 fmt.Println(a) // [42 2 3], c es una copia independiente
Historia
El servicio de filtrado de datos comenzó a devolver resultados inesperados: Un desarrollador pasaba slices entre varias funciones sin copiar, cambiando su estado. Debido a las modificaciones en los slices en diferentes lugares, la lógica de la aplicación se rompía y se encontraban extraños errores en los datos que no podían ser detectados durante mucho tiempo.
Historia
Pérdida de datos después de pasar una estructura: En un proyecto, al serializar datos, se eliminó por error un campo obligatorio de la estructura porque el objeto se pasaba por referencia y no se creaba su copia. Como resultado, se perdió información crítica en producción debido a esto.
Historia
Error de trabajo paralelo con map: Un desarrollador copió la referencia de un map, pensando que los cambios no afectarían al original, como sucede en otros lenguajes. Esto provocó una carrera de datos al trabajar en diferentes goroutines, lo que llevó a caídas de la aplicación.