Penerima Penuding pada Kaedah
Mengubah keadaan struct melalui penerima penuding
Penerima Penuding pada Kaedah ialah pelajaran Go Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Go Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Go Academy merangkumi sejumlah 4 pelajaran.
Ringkasan: Penerima Nilai berbanding Penuding
Penerima nilai beroperasi pada salinan struktur. Penerima penuding beroperasi pada nilai asal. Gunakan penerima penuding apabila kaedah perlu mengubah suai keadaan.
Pengubahan dengan Penerima Penuding
Hanya penerima penuding boleh mengubah suai struktur:
package main
import "fmt"
type Stack struct{ items []int }
func (s *Stack) Push(v int) { s.items = append(s.items, v) }
func (s *Stack) Pop() int {
n := len(s.items) - 1
v := s.items[n]
s.items = s.items[:n]
return v
}
func main() {
var st Stack
st.Push(1); st.Push(2)
fmt.Println(st.Pop()) // 2
}Peraturan Keseragaman
Jika mana-mana kaedah pada sesuatu jenis memerlukan penerima penuding, semua kaedah hendaklah menggunakan penerima penuding. Percampuran menyebabkan masalah dengan pemenuhan antara muka:
package main
import "fmt"
type Counter struct{ n int }
func (c *Counter) Inc() { c.n++ } // pointer
func (c *Counter) Val() int { return c.n } // pointer too
func main() {
c := &Counter{}
c.Inc(); c.Inc()
fmt.Println(c.Val()) // 2
}Pemenuhan Antara Muka
Kaedah penerima penuding hanya terdapat dalam set kaedah *T, bukan T. Hal ini mempengaruhi pemenuhan antara muka:
package main
import "fmt"
type Writer interface{ Write([]byte) }
type File struct{ name string }
func (f *File) Write(b []byte) { fmt.Println(string(b)) }
func main() {
var w Writer = &File{"out.txt"} // OK
// var w Writer = File{} — compile error
w.Write([]byte("hello"))
}Pengambilan Alamat Automatik
Go mengambil alamat secara automatik apabila memanggil kaedah penerima penuding pada nilai yang boleh dialamatkan:
package main
import "fmt"
type Box struct{ V int }
func (b *Box) Double() { b.V *= 2 }
func main() {
b := Box{5}
b.Double() // Go does (&b).Double()
fmt.Println(b.V) // 10
}Nilai yang Tidak Boleh Dialamatkan
Anda tidak boleh memanggil kaedah penerima penuding pada nilai yang tidak boleh dialamatkan (elemen peta dan nilai pemulangan fungsi yang tidak ditugaskan kepada pemboleh ubah):
package main
type T struct{ V int }
func (t *T) Set(v int) { t.V = v }
func getT() T { return T{} }
func main() {
var t T
t.Set(1) // OK — t is addressable
// getT().Set(1) — ERROR: cannot take address of getT()
_ = t
}Penerima Struktur Besar
Sentiasa gunakan penerima penuding untuk struktur besar bagi mengelakkan salinan yang mahal pada setiap panggilan kaedah:
package main
type Image struct{ pixels [1024][1024]uint8 }
// Value receiver copies 1MB per call!
func (img Image) Bad() uint8 { return img.pixels[0][0] }
// Pointer receiver — zero copy
func (img *Image) Good() uint8 { return img.pixels[0][0] }
func main() { _ = Image{} }Penerima Penuding <code>nil</code>
Kaedah dengan penerima penuding boleh mengendalikan nil dengan selamat:
package main
import "fmt"
type List struct{ head *node }
type node struct{ val int; next *node }
func (l *List) Len() int {
if l == nil { return 0 }
count := 0
for n := l.head; n != nil; n = n.next { count++ }
return count
}
func main() {
var l *List
fmt.Println(l.Len()) // 0
}Pembenaman dan Penerima Penuding
Apabila membenamkan jenis dengan penerima penuding, struktur luar juga mesti digunakan sebagai penuding untuk mendapatkan kaedah yang dinaikkan:
package main
import "fmt"
type Base struct{ V int }
func (b *Base) Set(v int) { b.V = v }
type Derived struct{ Base }
func main() {
d := &Derived{}
d.Set(42) // promoted pointer-receiver method
fmt.Println(d.V) // 42
}Penyalinan Mutex
Jangan sekali-kali menyalin struktur yang mengandungi sync.Mutex — sentiasa gunakan penerima penuding atau hantar melalui penuding. Menyalin mutex yang dikunci menyebabkan kebuntuan:
package main
import "sync"
type Safe struct {
mu sync.Mutex
v int
}
// Correct: pointer receiver
func (s *Safe) Set(v int) {
s.mu.Lock()
defer s.mu.Unlock()
s.v = v
}
func main() { _ = Safe{} }go vet Mengesan Kesilapan
Jalankan go vet ./... untuk mengesan kesilapan penerima penuding yang biasa, seperti menyalin mutex dan kunci. Ia merupakan sebahagian daripada saluran go build dan semakan CI.
Semakan Pantas
Dalam set kaedah jenis manakah kaedah penerima penuding berada?
Ringkasan
Perkara utama:
- Penerima penuding mengubah suai; penerima nilai tidak
- Pastikan semua kaedah pada sesuatu jenis menggunakan jenis penerima yang sama
- Hanya
*Tmemenuhi antara muka yang memerlukan kaedah penerima penuding - Jangan sekali-kali menyalin struktur dengan mutex — gunakan penerima penuding
Arahan Latihan
Laksanakan struktur Queue dengan kaedah penerima penuding Enqueue(int), Dequeue() (int, bool) dan Len() int yang disokong oleh kepingan []int.
Pelajari Go dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 51
- Pelajaran
- 203
Soalan Lazim
Adakah pelajaran “Penerima Penuding pada Kaedah” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Go Academy, termasuk “Penerima Penuding pada Kaedah”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Go Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Penerima Penuding pada Kaedah”?
Mengubah keadaan struct melalui penerima penuding Anda berlatih Go Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Go Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Go Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.
Berapa lamakah pelajaran “Penerima Penuding pada Kaedah” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Go Academy ini?
Ya. Setiap pelajaran Go Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Apakah Penuding?
- Penuding dan Fungsi
- Penerima Penuding pada Kaedah
- new() dan Bila Perlu Menggunakan Penuding