Mari kita pertimbangkan contoh mudah: senarai yang dipautkan. Tanpa generik, anda akan mempunyai , , dan lain -lain. Dengan generik, kita boleh menentukan satu
di manamewakili jenis data yang akan dipegang oleh senarai. Prinsip yang sama digunakan untuk algoritma yang lebih kompleks seperti algoritma penyortiran (mis., Quicksort, Mergesort) yang boleh dilaksanakan secara umum, beroperasi pada kepingan mana -mana jenis setanding. Kuncinya adalah menggunakan kekangan
atau menentukan kekangan tersuai (seperti yang dibincangkan di bawah) untuk menentukan jenis yang dibenarkan untuk fungsi generik dan struktur data anda. Pelaksanaan Generik GO menggunakan teknik yang dipanggil monomorphization. Ini bermakna bahawa pada masa penyusunan, pengkompil menghasilkan pelaksanaan yang berasingan dan konkrit kod generik anda untuk setiap jenis tertentu yang digunakan. Ini mengelakkan overhead runtime yang dikaitkan dengan pelaksanaan generik yang lebih dinamik yang terdapat dalam beberapa bahasa lain. Anda mungkin melihat sedikit peningkatan saiz binari kerana pelbagai pelaksanaan yang dihasilkan, tetapi ini biasanya diabaikan melainkan jika anda mempunyai sejumlah besar jenis yang digunakan dengan kod generik yang sama. Dalam kebanyakan kes, kebolehgunaan semula kod yang lebih baik dan kebolehkerjaan melebihi prestasi yang berpotensi kecil. Penanda aras sentiasa disyorkan untuk mengesahkan ciri -ciri prestasi dalam aplikasi tertentu. Mereka membolehkan anda menentukan sekatan ke atas jenis yang boleh digunakan dengan fungsi generik dan struktur data anda. Kekangan yang paling mudah ialah, yang bermaksud parameter jenis boleh menjadi jenis. Walau bagaimanapun, untuk banyak algoritma, anda memerlukan kekangan yang lebih spesifik. LinkedListInt
Sebagai contoh, algoritma penyortiran memerlukan parameter jenis untuk dibandingkan. GO tidak mempunyai kekangan terbina dalam "setanding", jadi anda perlu menentukan sendiri menggunakan antara muka:
type Node[T any] struct { data T next *Node[T] } type LinkedList[T any] struct { head *Node[T] } func (ll *LinkedList[T]) Append(data T) { newNode := &Node[T]{data: data} if ll.head == nil { ll.head = newNode return } current := ll.head for current.next != nil { current = current.next } current.next = newNode } // ... other LinkedList methods (Prepend, Delete, etc.) ...
ini Ordered
antara muka secara tersirat mengekang T
menjadi salah satu jenis setanding yang disenaraikan. Anda boleh membuat kekangan yang lebih kompleks dengan menggabungkan antara muka atau menentukan antara muka tersuai. Berkesan menggunakan kekangan membantu mencegah kesilapan runtime dan meningkatkan kejelasan kod dengan menyatakan secara jelas keperluan kod generik anda. Kekangan yang jelas menjadikan fungsi generik dan struktur data anda lebih mantap dan lebih mudah difahami. wujud:
terlalu banyak : manakala
menyediakan fleksibiliti maksimum, ia juga boleh membawa kepada kod yang kurang efisien atau kesilapan runtime jika fungsi generik bergantung pada sifat jenis tertentu yang tidak dijamin oleh. Gunakan kekangan yang lebih spesifik apabila mungkin. Jangan lupa untuk mengendalikan kesilapan ini dengan sewajarnya untuk mengelakkan tingkah laku yang tidak dijangka. Elakkan mewujudkan pelaksanaan generik yang terlalu kompleks yang lebih sukar difahami dan diselenggarakan daripada pelaksanaan khusus jenis yang berasingan. Kesederhanaan adalah kunci. Elakkan peruntukan yang tidak perlu, terutamanya dalam gelung, untuk mengelakkan kemerosotan prestasi. Kekangan yang terlalu ketat mengehadkan kebolehgunaan semula, sementara kekangan yang terlalu longgar boleh menyebabkan kesilapan runtime.
Atas ialah kandungan terperinci Bagaimanakah saya boleh memanfaatkan generik untuk melaksanakan struktur data dan algoritma biasa di GO?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!