"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > ## Por que não posso simplesmente copiar instâncias de tipos com receptores de ponteiro no Go?

## Por que não posso simplesmente copiar instâncias de tipos com receptores de ponteiro no Go?

Publicado em 2024-11-08
Navegar:562

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

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.

Tutorial mais recente Mais>

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