Compreendendo receptores de ponteiro e instâncias de cópia
No Go, um método pode ser definido com um receptor de valor ou um receptor de ponteiro. Quando todos os métodos de um tipo T têm um tipo receptor do próprio T, é seguro copiar instâncias desse tipo, pois chamar qualquer um de seus métodos necessariamente faz uma cópia.
No entanto, a situação muda quando um tipo possui métodos com um receptor de ponteiro. Nesse caso, copiar instâncias desse tipo deve ser evitada, pois pode violar invariantes internos.
O problema com a cópia de ponteiros
Vamos considerar um exemplo para ilustrar o emitir. Suponha que temos um tipo Wrapper com dois campos: um valor v e um ponteiro p. Pretendemos armazenar o mesmo número em v e no valor apontado de p. Para garantir isso, fornecemos um método Set com um receptor de ponteiro:
type Wrapper struct {
v int
p *int
}
func (w *Wrapper) Set(v int) {
w.v = v
*w.p = v
}
Se tivermos uma instância de Wrapper e chamarmos o método Set, ele modificará o valor apontado de p. No entanto, se fizermos uma cópia da instância, a cópia compartilhará o mesmo valor de ponteiro p da instância original. Isso significa que quaisquer chamadas de método subsequentes em qualquer instância afetarão ambas as cópias.
Exemplo:
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)
Saída:
a.v=0, a.p=0; b.v=0, b.p=0 a.v=1, a.p=1; b.v=0, b.p=1
Neste exemplo, o valor de b torna-se inválido depois que a.Set(1) é chamado, pois b.v não é igual a *b.p. Isso ocorre porque o ponteiro p em a e b aponta para o mesmo valor subjacente.
Para evitar tais problemas, é recomendado trabalhar com valores de ponteiro ao usar métodos com receptores de ponteiro. Alternativamente, se o tipo puder ter apenas receptores de valor, é seguro copiar instâncias desse tipo, independentemente das chamadas de método.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3