Dalam Go, kaedah dengan penerima penuding diketahui dapat mengekalkan nilai asal pembolehubah yang dikendalikannya pada. Walau bagaimanapun, nampaknya terdapat percanggahan yang ketara apabila kaedah menjangkakan hujah penunjuk dan diberikan nilai bukan penunjuk.
Pertimbangkan coretan di bawah untuk Latihan 51 dalam Jelajah Perjalanan:
func (v *Vertex) Scale(f float64) { v.X *= f v.Y *= f } func main() { v := &Vertex{3, 4} v.Scale(2) fmt.Println(v) // Output: &{6 8} }
Menurut penjelasan, kaedah Skala tidak boleh mengubah suai v kerana ia menerima penunjuk ke Puncak (*Puncak) bukannya Vertex itu sendiri.
Walau bagaimanapun, apabila kita menukar baris v := &Vertex{3, 4} kepada v := Vertex{3, 4} secara utama, output berubah daripada &{6 8} kepada {6 8} (perhatikan yang hilang &). Ini menunjukkan bahawa v telah diubah suai, walaupun ia diluluskan sebagai nilai bukan penuding.
Kuncinya terletak pada sifat taip kuat Go dan pengoptimuman pengkompil. Walaupun kaedah Skala mengharapkan penerima penuding, ia masih boleh menerima nilai bukan penuding kerana Go secara tersirat menukarnya kepada penuding.
Secara khusus, pengkompil menulis semula kod berikut:
v := Vertex{3, 4} v.Scale(2)
kepada:
(&v).Scale(2)
Ini bermakna kaedah sebenarnya dipanggil dengan penunjuk kepada v, yang membenarkannya mengubah suai nilai asal.
Peraturan khusus Go berikut menerangkan tingkah laku ini:
Panggilan kaedah x.m() adalah sah jika set kaedah (jenis) x mengandungi m dan senarai hujah boleh diberikan kepada senarai parameter m. Jika x boleh dialamatkan dan set kaedah &x mengandungi m, x.m() ialah singkatan untuk (&x).m().
Ringkasnya, kaedah dengan penerima penuding masih boleh mengubah suai pembolehubah bukan penuding kerana pengkompil secara automatik menukar mereka ke penunjuk untuk mengekalkan keselamatan jenis kaedah.
Atas ialah kandungan terperinci Mengapa Kaedah Pergi dengan Penerima Penunjuk Mengubah Hujah Bukan Penunjuk?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!