"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ## ¿Por qué no puedo simplemente copiar instancias de tipos con receptores de puntero en Go?

## ¿Por qué no puedo simplemente copiar instancias de tipos con receptores de puntero en Go?

Publicado el 2024-11-08
Navegar:243

## Why Can\'t I Just Copy Instances of Types With Pointer Receivers in Go?

Comprensión de los receptores de puntero y copia de instancias

En Go, se puede definir un método con un receptor de valor o un receptor de puntero. Cuando todos los métodos de un tipo T tienen un tipo receptor de T, es seguro copiar instancias de ese tipo, ya que llamar a cualquiera de sus métodos necesariamente hace una copia.

Sin embargo, la situación cambia cuando un tipo tiene métodos con un receptor de puntero. En este caso, se debe evitar copiar instancias de ese tipo, ya que puede violar invariantes internas.

El problema con la copia de punteros

Consideremos un ejemplo para ilustrar el asunto. Supongamos que tenemos un tipo Wrapper con dos campos: un valor v y un puntero p. Tenemos la intención de almacenar el mismo número tanto en v como en el valor señalado de p. Para garantizar esto, proporcionamos un método Set con un receptor de puntero:

type Wrapper struct {
    v int
    p *int
}

func (w *Wrapper) Set(v int) {
    w.v = v
    *w.p = v
}

Si tenemos una instancia de Wrapper y llamamos al método Set, modificará el valor señalado de p. Sin embargo, si hacemos una copia de la instancia, la copia compartirá el mismo valor de puntero p que la instancia original. Esto significa que cualquier llamada a método posterior en cualquiera de las instancias afectará a ambas copias.

Ejemplo:

a := Wrapper{v: 0, p: new(int)}
b := a

fmt.Printf("a.v=%d, a.p=%d;  b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)

a.Set(1)
fmt.Printf("a.v=%d, a.p=%d;  b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)

Salida:

a.v=0, a.p=0;  b.v=0, b.p=0
a.v=1, a.p=1;  b.v=0, b.p=1

En este ejemplo, el valor de b deja de ser válido después de llamar a a.Set(1), ya que b.v no es igual a *b.p. Esto se debe a que el puntero p tanto en a como en b apunta al mismo valor subyacente.

Para evitar este tipo de problemas, se recomienda trabajar con valores de puntero cuando se utilizan métodos con receptores de puntero. Alternativamente, si el tipo solo puede tener receptores de valores, es seguro copiar instancias de ese tipo independientemente de las llamadas al método.

Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3