ProgramaciónDesarrollador Backend de Go

Describa las características de la copia de slices y estructuras en Go. ¿Cómo evitar efectos inesperados al trabajar con ellos?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

Las estructuras en Go se copian por valor (copia profunda de primer nivel, las estructuras anidadas se copian según la misma regla), mientras que los slices se copian por valor, pero solo se copia la estructura, no el array de datos subyacente: tanto el original como la copia del slice apuntan al mismo array de respaldo, por lo que un cambio a través de un slice se reflejará en el otro, a menos que se haga una copia explícita del array mediante copy().

Ejemplo de copia de un slice:

s1 := []int{1,2,3} s2 := s1 // ¡punteros al mismo buffer! s2[0] = 99 fmt.Println(s1) // [99 2 3] // Para copiar el array: s3 := make([]int, len(s1)) copy(s3, s1) s3[0] = 42 fmt.Println(s1) // [99 2 3], s3 es independiente

Al copiar estructuras: si la estructura contiene un campo puntero o un campo slice, solo se copian las referencias y no los valores.

Pregunta trampa

¿Cuál es la forma de "clonar" un slice para que sus cambios no afecten al original?

Respuesta potencialmente errónea: Simplemente hacer b := a. Correcto:

  • Debe usar copy, crear un nuevo slice de la longitud necesaria y copiar los datos:
newS := make([]int, len(a)) copy(newS, a)

Ejemplos de errores reales debido al desconocimiento de las sutilezas del tema


Historia

Descripción: Al generar consultas a la base de datos, se cambiaban dinámicamente los campos del slice en la estructura de la consulta sin hacer copias. En solicitudes repetidas, los datos se cruzaban, dando resultados incorrectos para los usuarios.


Historia

Descripción: Al procesar datos en paralelo, se creaba una copia de la estructura mediante asignación y se ampliaba el slice en una gorutina, utilizando simultáneamente otro slice original. Los datos "se sobreescribían", lo que llevaba a errores impredecibles.


Historia

Descripción: Se utilizó una estructura de buffer, la copia simultánea mediante asignación no tenía en cuenta los slices anidados (copia superficial), los cambios en un lugar afectaban a otro buffer, lo que dificultaba rastrear la fuente de los cambios en los datos.