← Danh sách bài học Bài 12/20

🔌 Bài 12: Interface

⏱️ 25 phút | 📚 Nâng cao

🎯 Mục tiêu:

1. Interface Là Gì?

Interface định nghĩa tập hợp method signatures. Bất kỳ type nào implement đủ methods đó đều thỏa mãn interface.

// Định nghĩa interface
type Speaker interface {
    Speak() string
}

// Dog implement Speaker
type Dog struct{ Name string }
func (d Dog) Speak() string {
    return d.Name + " says: Gâu gâu!"
}

// Cat implement Speaker
type Cat struct{ Name string }
func (c Cat) Speak() string {
    return c.Name + " says: Meo meo!"
}

func main() {
    animals := []Speaker{
        Dog{Name: "Buddy"},
        Cat{Name: "Kitty"},
    }
    
    for _, animal := range animals {
        fmt.Println(animal.Speak())
    }
}
💡 Duck Typing: "If it walks like a duck and quacks like a duck, it's a duck." - Không cần khai báo explicit implements.

2. Interface Trong Thực Tế

// io.Reader - đọc dữ liệu
type Reader interface {
    Read(p []byte) (n int, err error)
}

// io.Writer - ghi dữ liệu
type Writer interface {
    Write(p []byte) (n int, err error)
}

// Nhiều types implement Reader/Writer:
// os.File, bytes.Buffer, http.Response.Body...

3. Empty Interface (any)

interface{} chấp nhận BẤT KỲ type nào.

func printAnything(x interface{}) {
    fmt.Println(x)
}

// Hoặc dùng alias 'any' (Go 1.18+)
func printAny(x any) {
    fmt.Println(x)
}

func main() {
    printAnything(42)
    printAnything("hello")
    printAnything(true)
    printAnything([]int{1, 2, 3})
}

4. Type Assertion

var x interface{} = "hello"

// Lấy giá trị với kiểu cụ thể
s := x.(string)
fmt.Println(s)  // hello

// An toàn hơn với ok
s2, ok := x.(string)
if ok {
    fmt.Println("It's a string:", s2)
}

// Panic nếu sai kiểu!
// n := x.(int)  // panic!

5. Type Switch

func describe(x interface{}) {
    switch v := x.(type) {
    case int:
        fmt.Println("Int:", v*2)
    case string:
        fmt.Println("String:", len(v), "chars")
    case bool:
        fmt.Println("Bool:", v)
    default:
        fmt.Println("Unknown type")
    }
}

func main() {
    describe(42)      // Int: 84
    describe("Go")    // String: 2 chars
    describe(true)    // Bool: true
}

📝 Tóm Tắt