Rumah >pembangunan bahagian belakang >Golang >## Mengapa Saya Tidak Boleh Menyalin Contoh Jenis Dengan Penerima Penunjuk dalam 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!