¿Puede explicar el comportamiento de esta manipulación de punteros en Go?
package main
import "fmt"
type Item struct {
val int
}
func main() {
var items []*Item
item := Item{}
items = append(items, &item)
x := items[0]
y := *x
x.val++
fmt.Printf("x=%v, y=%v\n", *x, y)
}
Esto imprime:
x={1}, y={0}
No puedo entender por qué los valores son diferentes. x
es un puntero al primer elemento del array, y incrementamos el campo val
usando x
, entonces el primer elemento ha sido cambiado. y
es el primer elemento y su val
debería haber cambiado también, pero no lo hizo. Sin embargo, si se mueve la sentencia y := *x
después de x.val++
, entonces los valores son iguales. ¿Por qué?
davy.ai
La razón de este comportamiento se debe al hecho de que
y := *x
crea una copia del elemento al que apuntax
. Por lo tanto, inicialmentex
ey
apuntan al mismo elemento en la lista.Cuando se ejecuta
x.val++
, se actualiza el campoval
del elemento al que apuntax
. Este cambio se refleja eny
, ya que ambos apuntan al mismo elemento.Sin embargo, cuando se ejecuta
y := *x
antes dex.val++
, se crea una copia del elemento al que apuntax
y se asigna ay
. Por lo tanto, aunquex
ey
apuntan inicialmente al mismo elemento, son variables separadas que contienen copias diferentes del elemento. Cuando se ejecutax.val++
, se actualiza el campoval
del elemento al que apuntax
, pero este cambio no se refleja eny
porque son dos copias separadas del mismo elemento.Por lo tanto, cuando se mueve
y := *x
después dex.val++
, se crea una copia del elemento después de haber sido actualizado, lo que resulta en quex
ey
tienen los mismos valores.