Go Generics
Definisi
Generics memungkinkan fungsi dan tipe bekerja dengan tipe apa pun tanpa kehilangan keamanan tipe. Di Go, generics ditulis dengan type parameter yang dibatasi oleh constraint (biasanya interface).
func Map[T any, U any](s []T, f func(T) U) []U {
out := make([]U, len(s))
for i, v := range s {
out[i] = f(v)
}
return out
}Kapan dipakai
Pakai generics kalau logikanya sama untuk banyak tipe: koleksi generic (Stack, Queue), helper Map/Filter/Reduce, atau struktur data yang tidak peduli tipe elemen. Jangan pakai generics buat satu tipe yang sudah jelas — cukup tulis tipe konkret, jangan over-abstract.
Cara kerja
Type parameter dan constraint
type Number interface {
~int | ~int64 | ~float64
}
func Sum[T Number](nums []T) T {
var total T
for _, n := range nums {
total += n
}
return total
}~int artinya "tipe dasarnya int", jadi type alias seperti type ID int juga lolos constraint.
Constraint bawaan
any— semua tipe (aliasinterface{}).comparable— tipe yang bisa dipakai di==/!=dan sebagai key map.
func Keys[K comparable, V any](m map[K]V) []K {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}Generic type
type Box[T any] struct {
Value T
}
func (b Box[T]) Get() T { return b.Value }Struktur alur
Loading diagram...
Contoh penggunaan
doubled := Map([]int{1, 2, 3}, func(n int) int { return n * 2 })
total := Sum([]float64{1.5, 2.5}) // 4.0
ids := Keys(map[string]int{"a": 1})Catatan implementasi
- Gunakan
anyuntuk batasan longgar, constraint spesifik (misalNumber) untuk operasi yang butuh operator tertentu. ~Tlebih fleksibel daripadaTpolos kalau ingin menerima alias tipe.- Constraint boleh berisi method, bukan cuma union tipe dasar.
Kesalahan umum
- Over-abstracting: membuat generic untuk satu penggunaan, malah menyulitkan pembacaan.
- Constraint terlalu sempit: lupa
~sehingga alias tipe ditolak. - Mengharapkan
anybisa dioprasikan:anytidak punya+atau<, harus di约束 dulu. - Generics di method receiver terpisah salah: type parameter dideklarasikan di nama tipe, bukan tiap method.