Generik dalam Go: Mengubah Kebolehgunaan Semula Kod
Generik, yang diperkenalkan dalam Go 1.18, telah merevolusikan cara menulis kod yang boleh digunakan semula dan selamat jenis. Generik membawa fleksibiliti dan kuasa sambil mengekalkan falsafah kesederhanaan Go. Walau bagaimanapun, memahami nuansa, faedah dan cara generik dibandingkan dengan pendekatan tradisional (seperti antara muka{} ) memerlukan pandangan yang lebih dekat.
Mari kita terokai selok-belok generik, teliti kekangan, bandingkan generik dengan antara muka{} dan tunjukkan aplikasi praktikalnya. Kami juga akan menyentuh pertimbangan prestasi dan implikasi saiz binari. Mari selami!
Apakah Generik?
Generik membolehkan pembangun menulis fungsi dan struktur data yang boleh beroperasi pada sebarang jenis sambil mengekalkan keselamatan jenis. Daripada bergantung pada antara muka{}, yang melibatkan penegasan jenis dalam masa jalan, generik membenarkan anda menentukan set kekangan yang menentukan operasi yang dibenarkan pada jenis.
Sintaks
func FunctionName[T TypeConstraint](parameterName T) ReturnType { // Function body using T }
T: Parameter jenis, mewakili ruang letak untuk jenis.
TypeConstraint: Mengehadkan jenis T kepada jenis tertentu atau set jenis.
parameterName T: Parameter menggunakan jenis generik T.
ReturnType: Fungsi ini juga boleh mengembalikan nilai jenis T.
Contoh
func Sum[T int | float64](a, b T) T { return a + b }
func Sum: Mengisytiharkan nama fungsi, Sum
[T int | float64]: Menentukan senarai parameter jenis yang memperkenalkan T sebagai parameter jenis, terhad kepada jenis tertentu (int atau float64). Fungsi sum boleh mengambil hanya parameter sama ada int atau float64, bukan digabungkan, kedua-duanya perlu sama ada int atau float64. Kami akan meneroka perkara ini dengan lebih lanjut dalam bahagian di bawah.
(a, b T): Mengisytiharkan dua parameter, a dan b, kedua-duanya jenis T (jenis generik ).
T: Menentukan jenis pemulangan fungsi, yang sepadan dengan parameter jenis T.
Kekangan: Blok pembinaan Generik
Kekangan menentukan operasi yang sah untuk jenis generik. Go menyediakan alatan berkuasa untuk kekangan, termasuk pakej kekangan percubaan(golang.org/x/exp/constraints).
Kekangan Terbina dalam
Perkenalkan kekangan terbina dalam dengan generik untuk menyediakan keselamatan jenis sambil membenarkan fleksibiliti dalam menentukan kod boleh guna semula dan generik. Kekangan ini membolehkan pembangun menguatkuasakan peraturan pada jenis yang digunakan dalam fungsi atau jenis generik.
Go mempunyai kekangan terbina dalam di bawah
- mana-mana: Mewakili sebarang jenis. Ia adalah alias untuk antara muka{}. Ini digunakan apabila tiada kekangan diperlukan
func FunctionName[T TypeConstraint](parameterName T) ReturnType { // Function body using T }
- setanding: Membenarkan jenis yang menyokong perbandingan kesaksamaan(== dan !=). Berguna untuk kunci peta, pengesanan pendua atau semakan kesaksamaan. Ini tidak boleh digunakan untuk peta, kepingan dan fungsi, kerana jenis ini tidak menyokong perbandingan langsung.
func Sum[T int | float64](a, b T) T { return a + b }
Kekangan eksperimen
- kekangan.Kompleks: Membenarkan jenis numerik kompleks(kompleks64 dan kompleks128).
- kekangan. Terapung: Membenarkan jenis angka terapung(float32 dan float64)
- kekangan.Integer: Membenarkan mana-mana integer ditandatangani dan tidak ditandatangani (int8, int16, int32, int64, int, uint8, uint16, uint32, uint64 dan uint)
- kekangan. Ditandatangani: Membenarkan mana-mana integer yang ditandatangani(int8, int16, int32, int64 dan int)
- kekangan.Tidak Ditandatangani: Membenarkan sebarang integer yang tidak ditandatangani (uint8, uint16, uint32, uint64 dan uint).
- kekangan.Tertib: Membenarkan jenis yang membenarkan perbandingan (<. <=, >, >=), semua jenis angka dan rentetan disokong(int, float64, rentetan, dsb.).
func PrintValues[T any](values []T) { for _, v := range values { fmt.Println(v) } }
Kekangan Tersuai
Kekangan tersuai ialah antara muka yang mentakrifkan satu set jenis atau gelagat jenis yang mesti dipenuhi oleh parameter jenis generik. Dengan mewujudkan kekangan anda sendiri, kami boleh;
Hadkan jenis kepada subset tertentu, seperti jenis angka.
Memerlukan jenis untuk melaksanakan kaedah atau tingkah laku tertentu.
Tambahkan lagi kawalan dan kekhususan pada fungsi dan jenis generik anda.
Sintaks
func CheckDuplicates[T comparable](items []T) []T { seen := make(map[T]bool) duplicates := []T{} for _, item := range items { if seen[item] { duplicates = append(duplicates, item) } else { seen[item] = true } } return duplicates }
Contoh
import ( "golang.org/x/exp/constraints" "fmt" ) func SortSlice[T constraints.Ordered](items []T) []T { sorted := append([]T{}, items...) // Copy slice sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] }) return sorted } func main() { nums := []int{5, 2, 9, 1} fmt.Println(SortSlice(nums)) // Output: [1 2 5 9] words := []string{"banana", "apple", "cherry"} fmt.Println(SortSlice(words)) // Output: [apple banana cherry] }
Fungsi jumlah boleh dipanggil hanya menggunakan parameter int, int64 dan float64.
Kekangan mengikut kaedah
Jika anda ingin menguatkuasakan sesuatu jenis mesti melaksanakan kaedah tertentu, anda boleh mentakrifkannya menggunakan kaedah tersebut.
type Numeric interface { int | float64 | uint }
Kekangan Formatter memerlukan sebarang jenis yang digunakan sebagai T mesti mempunyai kaedah Format yang mengembalikan rentetan.
Menggabungkan Kekangan
Kekangan tersuai boleh menggabungkan set jenis dan keperluan kaedah
type Number interface { int | int64 | float64 } func Sum[T Number](a, b T) T { return a + b }
Kekangan ini termasuk kedua-dua jenis khusus (int, float54) dan memerlukan kehadiran kaedah abs.
Generik lwn antara muka{}
Sebelum pengenalan generik, antara muka{} telah digunakan untuk mencapai fleksibiliti. Walau bagaimanapun, pendekatan ini mempunyai had.
Jenis Keselamatan
antara muka{}: Bergantung pada penegasan jenis masa jalan, meningkatkan peluang ralat semasa masa jalan.
Generik: Menawarkan keselamatan jenis masa kompilasi, menangkap ralat lebih awal semasa pembangunan.
Prestasi
antara muka{}: Lebih perlahan disebabkan pemeriksaan jenis masa jalan tambahan.
Generik: Lebih pantas, kerana pengkompil menjana laluan kod yang dioptimumkan khusus untuk jenis.
Kebolehbacaan Kod
antara muka{}: Selalunya bertele-tele dan kurang intuitif, menjadikan kod lebih sukar untuk dikekalkan.
Generik: Sintaks yang lebih bersih membawa kepada kod yang lebih intuitif dan boleh diselenggara.
Saiz Binari
antara muka{}: Hasil dalam binari yang lebih kecil kerana ia tidak menduplikasi kod untuk jenis yang berbeza.
Generik: Meningkatkan sedikit saiz binari disebabkan pengkhususan jenis untuk prestasi yang lebih baik.
Contoh
func FunctionName[T TypeConstraint](parameterName T) ReturnType { // Function body using T }
Kod berfungsi dengan baik, penegasan jenis berada di atas kepala. Fungsi tambah boleh dipanggil dengan sebarang argumen, kedua-dua parameter a dan b boleh terdiri daripada jenis yang berbeza, namun kod akan ranap dalam masa jalan.
func Sum[T int | float64](a, b T) T { return a + b }
Generik menghapuskan risiko panik masa jalan yang disebabkan oleh penegasan jenis yang salah dan meningkatkan kejelasan.
Prestasi
Generik menghasilkan kod khusus untuk setiap jenis, yang membawa kepada prestasi masa jalan yang lebih baik berbanding antara muka{}.
Saiz Binari
Pertukaran wujud: generik meningkatkan saiz binari disebabkan pertindihan kod untuk setiap jenis, tetapi ini selalunya boleh diabaikan berbanding dengan faedah.
Had Go Generics
Kerumitan dalam Kekangan: Walaupun kekangan seperti kekangan. Diperintahkan memudahkan kes penggunaan biasa, mentakrifkan kekangan yang sangat tersuai boleh menjadi bertele-tele.
Tiada Jenis Inferens dalam Struktur: Tidak seperti fungsi, anda mesti menyatakan parameter jenis secara eksplisit untuk struct.
func PrintValues[T any](values []T) { for _, v := range values { fmt.Println(v) } }
Terhad kepada Kekangan Masa Kompilasi: Generik Go memfokuskan pada keselamatan masa kompilasi, manakala bahasa seperti Rust menawarkan kekangan yang lebih berkuasa menggunakan jangka hayat dan sifat.
Mari Menanda Aras — Lebih baik dilakukan daripada dikatakan
Kami akan melaksanakan Baris Gilir mudah dengan kedua-dua antara muka{} dan generik serta menanda aras hasilnya.
Pelaksanaan baris gilir{} antara muka
func CheckDuplicates[T comparable](items []T) []T { seen := make(map[T]bool) duplicates := []T{} for _, item := range items { if seen[item] { duplicates = append(duplicates, item) } else { seen[item] = true } } return duplicates }
Pelaksanaan Giliran Generik
import ( "golang.org/x/exp/constraints" "fmt" ) func SortSlice[T constraints.Ordered](items []T) []T { sorted := append([]T{}, items...) // Copy slice sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] }) return sorted } func main() { nums := []int{5, 2, 9, 1} fmt.Println(SortSlice(nums)) // Output: [1 2 5 9] words := []string{"banana", "apple", "cherry"} fmt.Println(SortSlice(words)) // Output: [apple banana cherry] }
type Numeric interface { int | float64 | uint }
Analisis Keputusan
Masa Pelaksanaan:
Pelaksanaan generik adalah lebih kurang 63.64% lebih pantas daripada versi antara muka{} kerana ia mengelakkan penegasan jenis masa jalan dan beroperasi terus pada jenis yang diberikan.Peruntukan:
Versi antara muka{} membuat 3x lebih banyak peruntukan, terutamanya disebabkan oleh peninjuan/penyahkotak apabila memasukkan dan mendapatkan semula nilai. Ini menambah overhed kepada kutipan sampah.
Untuk beban kerja yang lebih besar, seperti 1 juta operasi enqueue/dequeue, jurang prestasi semakin melebar. Aplikasi dunia sebenar dengan keperluan pemprosesan tinggi (cth., baris gilir mesej, penjadual kerja) mendapat manfaat yang ketara daripada generik.
Fikiran Akhir
Generik dalam Go menyeimbangkan antara kuasa dan kesederhanaan, menawarkan penyelesaian praktikal untuk menulis kod yang boleh digunakan semula dan selamat jenis. Walaupun tidak kaya ciri seperti Rust atau C , selaras dengan sempurna dengan falsafah minimalis Go. Memahami kekangan seperti kekangan. Disusun dan memanfaatkan generik dengan berkesan boleh meningkatkan kualiti dan kebolehselenggaraan kod.
Memandangkan generik terus berkembang, mereka ditakdirkan untuk memainkan peranan penting dalam ekosistem Go. Jadi, selami, bereksperimen dan terima era baharu jenis keselamatan dan fleksibiliti dalam pengaturcaraan Go!
Lihat repositori github untuk beberapa sampel pada generik.
sadananddodawadakar
/
GoGenerics
Repositori mengandungi contoh kerja generik go
Go Generics: Repositori Contoh Komprehensif
Selamat datang ke Repositori Go Generics! Repositori ini ialah sumber sehenti untuk memahami, mempelajari dan menguasai generik dalam Go, yang diperkenalkan dalam versi 1.18. Generik membawa kuasa parameter jenis kepada Go, membolehkan pembangun menulis kod boleh guna semula dan selamat taip tanpa menjejaskan prestasi atau kebolehbacaan.
Repositori ini mengandungi contoh susun atur dengan teliti yang merangkumi pelbagai topik, daripada sintaks asas kepada corak lanjutan dan kes penggunaan praktikal. Sama ada anda seorang pemula atau pembangun Go yang berpengalaman, koleksi ini akan membantu anda memanfaatkan generik dengan berkesan dalam projek anda.
? Apa Ada Dalam
? Program Asas Generik
Contoh ini memperkenalkan konsep asas generik, membantu anda memahami sintaks dan ciri teras:
- GenericMap: Menunjukkan fungsi peta generik untuk mengubah kepingan apa-apa jenis.
- Tukar: Contoh mudah tetapi berkesan untuk menukar dua nilai secara umum.
- FilterSlice: Menunjukkan cara menapis…
Atas ialah kandungan terperinci Generik dalam Go: Mengubah Kebolehgunaan Semula Kod. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas











Pergi bahasa berfungsi dengan baik dalam membina sistem yang cekap dan berskala. Kelebihannya termasuk: 1. Prestasi Tinggi: Disusun ke dalam Kod Mesin, Kelajuan Berjalan Cepat; 2. Pengaturcaraan serentak: Memudahkan multitasking melalui goroutine dan saluran; 3. Kesederhanaan: sintaks ringkas, mengurangkan kos pembelajaran dan penyelenggaraan; 4. Cross-Platform: Menyokong kompilasi silang platform, penggunaan mudah.

Golang lebih baik daripada C dalam kesesuaian, manakala C lebih baik daripada Golang dalam kelajuan mentah. 1) Golang mencapai kesesuaian yang cekap melalui goroutine dan saluran, yang sesuai untuk mengendalikan sejumlah besar tugas serentak. 2) C Melalui pengoptimuman pengkompil dan perpustakaan standard, ia menyediakan prestasi tinggi yang dekat dengan perkakasan, sesuai untuk aplikasi yang memerlukan pengoptimuman yang melampau.

Golang dan Python masing -masing mempunyai kelebihan mereka sendiri: Golang sesuai untuk prestasi tinggi dan pengaturcaraan serentak, sementara Python sesuai untuk sains data dan pembangunan web. Golang terkenal dengan model keserasiannya dan prestasi yang cekap, sementara Python terkenal dengan sintaks ringkas dan ekosistem perpustakaan yang kaya.

Golang lebih baik daripada Python dari segi prestasi dan skalabiliti. 1) Ciri-ciri jenis kompilasi Golang dan model konkurensi yang cekap menjadikannya berfungsi dengan baik dalam senario konvensional yang tinggi. 2) Python, sebagai bahasa yang ditafsirkan, melaksanakan perlahan -lahan, tetapi dapat mengoptimumkan prestasi melalui alat seperti Cython.

Golang dan C masing-masing mempunyai kelebihan sendiri dalam pertandingan prestasi: 1) Golang sesuai untuk kesesuaian tinggi dan perkembangan pesat, dan 2) C menyediakan prestasi yang lebih tinggi dan kawalan halus. Pemilihan harus berdasarkan keperluan projek dan tumpukan teknologi pasukan.

Goimpactsdevelopmentpositivielythroughspeed, efficiency, andsimplicity.1) Speed: goCompilesquicklyandrunsefficiently, idealforlargeproject.2) Kecekapan: ITSComprehensivestandardlibraryraryrarexternaldependencies, enhingdevelyficiency.

C lebih sesuai untuk senario di mana kawalan langsung sumber perkakasan dan pengoptimuman prestasi tinggi diperlukan, sementara Golang lebih sesuai untuk senario di mana pembangunan pesat dan pemprosesan konkurensi tinggi diperlukan. Kelebihan 1.C terletak pada ciri-ciri perkakasan dan keupayaan pengoptimuman yang tinggi, yang sesuai untuk keperluan berprestasi tinggi seperti pembangunan permainan. 2. Kelebihan Golang terletak pada sintaks ringkas dan sokongan konvensional semulajadi, yang sesuai untuk pembangunan perkhidmatan konvensional yang tinggi.

Perbezaan prestasi antara Golang dan C terutamanya ditunjukkan dalam pengurusan ingatan, pengoptimuman kompilasi dan kecekapan runtime. 1) Mekanisme pengumpulan sampah Golang adalah mudah tetapi boleh menjejaskan prestasi, 2) Pengurusan memori manual C dan pengoptimuman pengkompil lebih cekap dalam pengkomputeran rekursif.
