Rumah  >  Artikel  >  pembangunan bahagian belakang  >  ## Mengapa Saya Tidak Boleh Menyalin Contoh Jenis Dengan Penerima Penunjuk dalam Go?

## Mengapa Saya Tidak Boleh Menyalin Contoh Jenis Dengan Penerima Penunjuk dalam Go?

Linda Hamilton
Linda Hamiltonasal
2024-10-25 05:03:02171semak imbas

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

Memahami Penerima Penunjuk dan Menyalin Kejadian

Dalam Go, kaedah boleh ditakrifkan sama ada dengan penerima nilai atau penerima penunjuk. Apabila semua kaedah jenis T mempunyai jenis penerima T itu sendiri, adalah selamat untuk menyalin contoh jenis itu, kerana memanggil mana-mana kaedahnya semestinya membuat salinan.

Walau bagaimanapun, situasi berubah apabila jenis mempunyai kaedah dengan penerima penunjuk. Dalam kes ini, penyalinan contoh jenis itu harus dielakkan, kerana ia mungkin melanggar invarian dalaman.

Masalah dengan Menyalin Penunjuk

Mari kita pertimbangkan contoh untuk menggambarkan isu. Katakan kita mempunyai jenis Wrapper dengan dua medan: nilai v dan penunjuk p. Kami berhasrat untuk menyimpan nombor yang sama dalam kedua-dua v dan nilai titik p. Untuk memastikan ini, kami menyediakan kaedah Set dengan penerima penuding:

<code class="go">type Wrapper struct {
    v int
    p *int
}

func (w *Wrapper) Set(v int) {
    w.v = v
    *w.p = v
}</code>

Jika kami mempunyai contoh Wrapper dan memanggil kaedah Set, ia akan mengubah suai nilai titik p. Walau bagaimanapun, jika kita membuat salinan contoh, salinan itu akan berkongsi nilai penunjuk yang sama p seperti contoh asal. Ini bermakna bahawa mana-mana kaedah seterusnya memanggil salah satu contoh akan menjejaskan kedua-dua salinan.

Contoh:

<code class="go">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)</code>

Output:

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

Dalam contoh ini, nilai b menjadi tidak sah selepas a.Set(1) dipanggil, kerana b.v tidak sama dengan *b.p. Ini kerana penunjuk p dalam kedua-dua a dan b menunjukkan kepada nilai asas yang sama.

Untuk mengelakkan isu sedemikian, adalah disyorkan untuk menggunakan nilai penunjuk apabila menggunakan kaedah dengan penerima penunjuk. Sebagai alternatif, jika jenis boleh mempunyai penerima nilai sahaja, adalah selamat untuk menyalin tika jenis itu tanpa mengira panggilan kaedah.

Atas ialah kandungan terperinci ## Mengapa Saya Tidak Boleh Menyalin Contoh Jenis Dengan Penerima Penunjuk dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn