Generics
🧬 1. Generics là gì?
Generics trong Golang (từ Go 1.18) cho phép bạn viết hàm, interface và struct có thể hoạt động với nhiều kiểu dữ liệu mà không phải lặp code cho từng kiểu cụ thể. Nó giúp code reuse mà vẫn đảm bảo type safety.
📦 2. Cú pháp cơ bản
func PrintSlice[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
T
là type parameter.any
là constraint (giới hạn) — ở đây, nghĩa là chấp nhận mọi kiểu.PrintSlice[int]([]int{1, 2, 3})
vàPrintSlice[string]([]string{"a", "b"})
đều dùng được.
🧱 3. Generics với Struct
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(v T) {
s.items = append(s.items, v)
}
func (s *Stack[T]) Pop() T {
l := len(s.items)
val := s.items[l-1]
s.items = s.items[:l-1]
return val
}
Cách dùng:
intStack := Stack[int]{}
intStack.Push(10)
fmt.Println(intStack.Pop())
stringStack := Stack[string]{}
stringStack.Push("hello")
fmt.Println(stringStack.Pop())
⛓️ 4. Generics với Constraints
Bạn có thể giới hạn kiểu T
phải thỏa điều kiện nhất định, ví dụ:
type Number interface {
~int | ~float64
}
func Sum[T Number](a, b T) T {
return a + b
}
Ví dụ thực tế:
fmt.Println(Sum(3, 5)) // int
fmt.Println(Sum(3.2, 4.8)) // float64
🔁 5. Generics với Interface – Comparable
func FindIndex[T comparable](slice []T, target T) int {
for i, v := range slice {
if v == target {
return i
}
}
return -1
}
Dùng:
fmt.Println(FindIndex([]string{"a", "b", "c"}, "b")) // 1
🧠 6. Một số constraint hữu ích từ golang.org/x/exp/constraints
golang.org/x/exp/constraints
import "golang.org/x/exp/constraints"
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
💼 7. Use Case trong Backend (gợi ý thực tế)
Ví dụ bạn có một function map cho slice:
func MapSlice[T any, R any](in []T, mapper func(T) R) []R {
var out []R
for _, v := range in {
out = append(out, mapper(v))
}
return out
}
Dùng:
users := []User{...}
userDTOs := MapSlice(users, func(u User) UserDTO {
return ConvertToDTO(u)
})
🧪 8. Khi nào KHÔNG nên dùng Generics?
Khi logic quá đơn giản, dùng
interface{}
có thể nhanh hơn.Khi performance critical (vì generics compile-time nhưng đôi khi tạo thêm boilerplate nếu lạm dụng).
📚 Tổng kết
🛠 Dễ viết code tái sử dụng
✅
🧯 Type-safe, không dùng interface{} tùy tiện
✅
🧱 Hỗ trợ struct, method, func, interface
✅
⚙ Cần hiểu constraint để tối ưu
✅
Last updated