KHOÁ HỌC Phần 2 — 20% còn lại Type system nâng cao

Type system nâng cao

C1. Type Assertion & Type Switch

Type assertion — "ép" interface về kiểu cụ thể

var i interface{} = "hello"

s := i.(string)        // "hello" — panic nếu sai kiểu
s, ok := i.(string)    // dạng an toàn, ok=false nếu sai

Type switch — check nhiều kiểu

func describe(v interface{}) {
    switch x := v.(type) {
    case int:
        fmt.Println("int:", x*2)
    case string:
        fmt.Println("string:", len(x))
    case nil:
        fmt.Println("nil")
    default:
        fmt.Println("khác")
    }
}

C2. Empty interface any

interface{} (Go 1.18+ đổi tên thành any) = chấp nhận mọi kiểu.

func printAny(v any) { fmt.Println(v) }

👉 Đánh đổi: mất kiểm tra kiểu compile-time → dễ bug. Ưu tiên generics (C5) nếu có thể.

C3. Struct embedding — Composition thay cho Inheritance

Go không có kế thừa (inheritance). Thay vào đó dùng embedding:

type Animal struct {
    Name string
}
func (a Animal) Speak() { fmt.Println(a.Name, "kêu") }

type Dog struct {
    Animal   // Nhúng — không có tên field
    Breed string
}

d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Husky"}
d.Speak()      // "Rex kêu" — GỌI được method của Animal trực tiếp
fmt.Println(d.Name) // "Rex" — TRUY CẬP field trực tiếp

Embedding interface — pattern rất mạnh

type ReadWriter interface {
    io.Reader
    io.Writer
}

C4. Struct tags — Metadata cho field

type User struct {
    ID    int    `json:"id" db:"user_id"`
    Name  string `json:"name" validate:"required,min=3"`
    Email string `json:"email,omitempty"`
    Pass  string `json:"-"`  // Không xuất ra JSON
}

👉 Được các thư viện đọc bằng reflection (JSON, ORM, validator...).

C5. Generics (Go 1.18+)

Trước generics — phải viết lặp

func SumInts(a []int) int { ... }
func SumFloats(a []float64) float64 { ... }

Với generics

type Number interface {
    int | float64 | int64  // Constraint: các kiểu cho phép
}

func Sum[T Number](nums []T) T {
    var total T
    for _, n := range nums {
        total += n
    }
    return total
}

Sum([]int{1,2,3})           // 6
Sum([]float64{1.5, 2.5})    // 4.0

Generic struct

type Stack[T any] struct {
    items []T
}
func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }

👉 Dùng khi: viết thư viện (container, utility). Tránh trong business logic — làm khó đọc.

← Hàm nâng cao