Memahami Penetap untuk Jenis Struktur
Dalam Go, struct boleh diubah suai melalui fungsi setter. Walau bagaimanapun, tingkah laku tertentu boleh tidak dijangka apabila menggunakan penetap untuk jenis struct. Pertimbangkan contoh berikut:
package main import "fmt" type T struct { Val string } // this setter seems not to work func (t T) SetVal(s string) { t.Val = s } // this setter, using ptr to T, seems to work ok func (t *T) SetVal2(s string) { (*t).Val = s } func main() { v := T{"abc"} fmt.Println(v) // prints {abc} v.SetVal("pdq") fmt.Println(v) // prints {abc}, was expecting {pdq}! v.SetVal2("xyz") fmt.Println(v) // prints {xyz}! }
Timbul persoalan: mengapa fungsi SetVal tidak mengubah suai struktur asal seperti yang dijangkakan?
Memahami Semantik Nilai
Perbezaan utama terletak pada cara struct dihantar ke fungsi. Apabila menghantar struct mengikut nilai (seperti dalam SetVal), salinan struct dibuat dalam fungsi. Sebarang perubahan yang dibuat dalam fungsi hanya akan menjejaskan salinan sementara ini, meninggalkan struct asal tidak berubah.
Walau bagaimanapun, apabila menghantar struct dengan penuding (seperti dalam SetVal2), fungsi mendapat akses kepada struct asal dalam memori. Sebarang perubahan yang dibuat dalam fungsi akan dicerminkan secara langsung dalam struct asal.
Semantik Bukti Nilai
Ini boleh digambarkan dengan mencetak alamat memori bagi struct yang terlibat :
package main import "fmt" type T struct { Val string } func (t T) SetVal(s string) { fmt.Printf("Address of copy is %p\n", &t) } func (t *T) SetVal2(s string) { fmt.Printf("Pointer argument is %p\n", t) } func main() { v := T{"abc"} fmt.Printf("Address of v is %p\n", &v) v.SetVal("pdq") v.SetVal2("xyz") }
Kod ini akan menghasilkan output menyerupai:
Address of v is 0xf840001290 Address of copy is 0xf8400013e0 Pointer argument is 0xf840001290
Perhatikan bahawa alamat pertama dan ketiga yang dicetak adalah sama, menunjukkan bahawa ia merujuk kepada struct yang sama. Walau bagaimanapun, alamat kedua adalah berbeza, mewakili salinan sementara yang dibuat dalam SetVal.
Atas ialah kandungan terperinci Mengapa Fungsi Penetap Go Struct Saya Tidak Mengubah Suai Struktur Asal?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!