Penerima Penunjuk dalam Golang dan Pelaksanaan Antara Muka
Dalam Go, fungsi penerima membenarkan kaedah beroperasi pada jenis tertentu. Apabila kaedah mempunyai penerima penuding, ia boleh mengubah suai contoh sebenar struct.
Memahami Isu
Pertimbangkan coretan kod berikut:
type IFace interface { SetSomeField(newValue string) GetSomeField() string } type Implementation struct { someField string } // Method with non-pointer receiver func (i Implementation) GetSomeField() string { return i.someField } // Method with non-pointer receiver func (i Implementation) SetSomeField(newValue string) { i.someField = newValue }
Dalam kod ini, kedua-dua kaedah mempunyai penerima bukan penuding. Ini bermakna apabila memanggil SetSomeField, ia mencipta salinan struct dan mengubah suai salinan tersebut. Contoh asal kekal tidak berubah.
Menggunakan Penerima Penunjuk
Untuk menukar kejadian sebenar, kaedah SetSomeField harus mempunyai penerima penunjuk:
// Method with pointer receiver func (i *Implementation) SetSomeField(newValue string) { i.someField = newValue }
Kini, SetSomeField boleh mengubah suai contoh asal. Walau bagaimanapun, ini menimbulkan isu apabila melaksanakan antara muka IFace:
package main import ( "fmt" ) type IFace interface { SetSomeField(newValue string) GetSomeField() string } type Implementation struct { someField string } // Method with pointer receiver func (i *Implementation) GetSomeField() string { return i.someField } // Method with pointer receiver func (i *Implementation) SetSomeField(newValue string) { i.someField = newValue } func Create() IFace { obj := Implementation{someField: "Hello"} return obj // Offending line } func main() { a := Create() // Assigning an Implementation value to an IFace variable a.SetSomeField("World") // Will panic because a is an Implementation value, not a pointer fmt.Println(a.GetSomeField()) }
Menyusun kod ini mengakibatkan panik kerana Cipta mengembalikan nilai Pelaksanaan, bukan penunjuk kepadanya. Untuk melaksanakan antara muka dengan penerima penunjuk, kaedah mesti diisytiharkan sebagai penerima penunjuk dan fungsi Cipta mesti mengembalikan penunjuk kepada Pelaksanaan.
type IFace interface { SetSomeField(newValue string) GetSomeField() string } type Implementation struct { someField string } // Method with pointer receiver func (i *Implementation) GetSomeField() string { return i.someField } // Method with pointer receiver func (i *Implementation) SetSomeField(newValue string) { i.someField = newValue } func Create() *Implementation { obj := Implementation{someField: "Hello"} return &obj } func main() { var a IFace a = Create() // Now assigning a pointer to Implementation to an IFace variable a.SetSomeField("World") fmt.Println(a.GetSomeField()) }
Sekarang, a ialah penunjuk kepada nilai Pelaksanaan, yang melaksanakan IFace dengan penerima penunjuk. Perubahan yang dibuat melalui SetSomeField akan mempengaruhi contoh asal.
Atas ialah kandungan terperinci Mengapakah Menggunakan Penerima Penunjuk dalam Pelaksanaan Antara Muka Go Memerlukan Penunjuk Pengembalian?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!