Dalam Go, struct ialah jenis agregat yang digunakan untuk mentakrif dan merangkum data. Ia membolehkan menggabungkan bidang pelbagai jenis. Structs boleh dilihat sebagai jenis data tersuai yang serupa dengan kelas dalam bahasa lain, tetapi ia tidak menyokong warisan. Kaedah ialah fungsi yang dikaitkan dengan jenis tertentu (selalunya struct) dan boleh dipanggil menggunakan tika jenis itu.
Struktur ditakrifkan menggunakan kata kunci jenis dan struktur. Berikut ialah contoh definisi struktur mudah:
type User struct { Username string Email string SignInCount int IsActive bool }
Struktur boleh dimulakan dalam pelbagai cara.
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
Jika sesetengah medan tidak dinyatakan, ia dimulakan kepada nilai sifarnya untuk jenis masing-masing.
user2 := User{ Username: "bob", }
Dalam contoh ini, E-mel akan dimulakan kepada rentetan kosong (""), SignInCount kepada 0 dan IsActive kepada false.
Struktur juga boleh dimulakan menggunakan penunjuk.
user3 := &User{ Username: "charlie", Email: "charlie@example.com", }
Dalam Go, struct bukan sahaja untuk menyimpan data tetapi juga boleh mempunyai kaedah yang ditentukan untuknya. Ini membolehkan struct untuk merangkum tingkah laku yang berkaitan dengan data mereka. Di bawah ialah penjelasan terperinci tentang kaedah dan tingkah laku struct.
Kaedah ditakrifkan menggunakan penerima, yang merupakan parameter pertama kaedah dan menentukan jenis kaedah tersebut. Penerima boleh sama ada penerima nilai atau penerima penunjuk.
Penerima nilai mencipta salinan struct apabila kaedah dipanggil, jadi pengubahsuaian pada medan tidak menjejaskan struct asal.
type User struct { Username string Email string } func (u User) PrintInfo() { fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email) }
Penerima penunjuk membenarkan kaedah untuk mengubah suai medan struct asal secara langsung.
func (u *User) UpdateEmail(newEmail string) { u.Email = newEmail }
Dalam Go, semua kaedah struct membentuk set kaedahnya. Kaedah yang ditetapkan untuk penerima nilai merangkumi semua kaedah dengan penerima nilai, manakala kaedah yang ditetapkan untuk penerima penunjuk merangkumi semua kaedah dengan kedua-dua penunjuk dan penerima nilai.
Kaedah struktur sering digunakan dengan antara muka untuk mencapai polimorfisme. Apabila mentakrifkan antara muka, anda menentukan kaedah yang mesti dilaksanakan oleh struct.
type UserInfo interface { PrintInfo() } // User implements the UserInfo interface func (u User) PrintInfo() { fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email) } func ShowInfo(ui UserInfo) { ui.PrintInfo() }
Dalam Go, penjajaran memori untuk struct direka untuk meningkatkan kecekapan capaian. Jenis data yang berbeza mempunyai keperluan penjajaran khusus dan pengkompil boleh memasukkan bait padding antara medan struct untuk memenuhi keperluan ini.
Penjajaran memori bermakna data dalam ingatan mesti terletak pada alamat yang berbilang nilai tertentu. Saiz jenis data menentukan keperluan penjajarannya. Contohnya, int32 memerlukan penjajaran kepada 4 bait dan int64 memerlukan penjajaran kepada 8 bait.
Akses memori yang cekap adalah penting untuk prestasi CPU. Jika pembolehubah tidak diselaraskan dengan betul, CPU mungkin memerlukan berbilang akses memori untuk membaca atau menulis data, yang membawa kepada kemerosotan prestasi. Dengan menjajarkan data, pengkompil memastikan capaian memori yang cekap.
Contoh:
type User struct { Username string Email string SignInCount int IsActive bool }
Output: 12
Analisis:
Anda boleh menyusun semula medan struct untuk meminimumkan padding dan mengurangkan penggunaan memori.
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
Output: 8
Dalam versi yang dioptimumkan ini, b diletakkan dahulu, menjajarkannya kepada 4 bait. a dan c diletakkan berturut-turut, menjadikan jumlah saiz 8 bait, yang lebih padat daripada versi yang tidak dioptimumkan.
Dalam Go, struktur dan komposisi bersarang ialah alat yang berkuasa untuk penggunaan semula kod dan mengatur data yang kompleks. Struk bersarang membenarkan struct memasukkan struct lain sebagai medan, membolehkan penciptaan model data yang kompleks. Komposisi, sebaliknya, mencipta struct baharu dengan memasukkan struct lain, memudahkan penggunaan semula kod.
Struktur bersarang membolehkan satu struct memasukkan struct lain sebagai medan. Ini menjadikan struktur data lebih fleksibel dan teratur. Berikut ialah contoh struct bersarang:
type User struct { Username string Email string SignInCount int IsActive bool }
Komposisi membenarkan berbilang struct digabungkan menjadi struct baharu, membolehkan penggunaan semula kod. Dalam komposisi, struct boleh memasukkan berbilang struct lain sebagai medan. Ini membantu membina model yang lebih kompleks dan berkongsi medan atau kaedah yang sama. Berikut ialah contoh komposisi struct:
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
Struktur dan komposisi bersarang ialah ciri berkuasa dalam Go yang membantu mengatur dan mengurus struktur data yang kompleks. Apabila mereka bentuk model data, menggunakan struktur dan gubahan bersarang dengan sewajarnya boleh menjadikan kod anda lebih jelas dan lebih boleh diselenggara.
Struktur kosong dalam Go ialah struct tanpa medan.
Struktur kosong menduduki sifar bait memori. Walau bagaimanapun, alamat ingatannya mungkin sama atau mungkin tidak sama dalam keadaan yang berbeza. Apabila pelarian memori berlaku, alamat adalah sama, menunjuk ke runtime.zerobase.
user2 := User{ Username: "bob", }
Daripada output, pembolehubah a, b dan zerobase berkongsi alamat yang sama, semuanya menunjuk kepada pembolehubah global runtime.zerobase (runtime/malloc.go).
Mengenai senario melarikan diri:
Tingkah laku ini disengajakan dalam Go. Apabila pembolehubah struct kosong tidak terlepas, penunjuknya adalah tidak sama. Selepas melarikan diri, penunjuk menjadi sama.
Struktur kosong itu sendiri tidak menduduki ruang, tetapi apabila dibenamkan dalam struktur lain, ia mungkin menggunakan ruang bergantung pada kedudukannya:
user3 := &User{ Username: "charlie", Email: "charlie@example.com", }
Apabila struct kosong ialah elemen tatasusunan atau kepingan:
type User struct { Username string Email string } func (u User) PrintInfo() { fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email) }
Sifat bersaiz sifar bagi struct kosong membolehkannya digunakan untuk pelbagai tujuan tanpa overhed memori tambahan.
type User struct { Username string Email string SignInCount int IsActive bool }
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
Kadangkala, kandungan data yang dihantar melalui saluran tidak relevan, hanya berfungsi sebagai isyarat. Sebagai contoh, struct kosong boleh digunakan dalam pelaksanaan semaphore:
user2 := User{ Username: "bob", }
Kami adalah Leapcell, pilihan utama anda untuk menggunakan projek Go ke awan.
Leapcell ialah Platform Tanpa Pelayan Generasi Seterusnya untuk Pengehosan Web, Tugas Async dan Redis:
Terokai lagi dalam Dokumentasi!
Ikuti kami di X: @LeapcellHQ
Baca di blog kami
Atas ialah kandungan terperinci Menyelam dalam Go Struct. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!