← Danh sách bài học
Bài 11/20
📍 Bài 11: Pointer (Con Trỏ)
🎯 Mục tiêu:
- Hiểu Pointer và địa chỉ bộ nhớ
- Toán tử & (lấy địa chỉ) và * (dereference)
- Pass by value vs Pass by reference
- Khi nào dùng pointer
1. Pointer Là Gì?
Pointer là biến lưu địa chỉ bộ nhớ của biến khác, không phải giá trị.
x := 42
p := &x // p lưu địa chỉ của x
fmt.Println(x) // 42 (giá trị)
fmt.Println(&x) // 0xc0000... (địa chỉ)
fmt.Println(p) // 0xc0000... (cùng địa chỉ)
fmt.Println(*p) // 42 (giá trị tại địa chỉ)
2. Toán Tử & và *
// & - lấy địa chỉ của biến
// * - lấy giá trị tại địa chỉ (dereference)
num := 100
ptr := &num // ptr = địa chỉ của num
fmt.Println(*ptr) // 100
*ptr = 200 // Thay đổi giá trị qua pointer
fmt.Println(num) // 200 (đã thay đổi!)
💡 Nhớ:
•
•
•
&variable → lấy địa chỉ•
*pointer → lấy giá trị tại địa chỉ
3. Pass by Value vs Pass by Reference
// Pass by value - COPY, không đổi gốc
func doubleValue(x int) {
x = x * 2
}
// Pass by reference - thay đổi gốc
func doublePointer(x *int) {
*x = *x * 2
}
func main() {
num := 10
doubleValue(num)
fmt.Println(num) // 10 (không đổi)
doublePointer(&num)
fmt.Println(num) // 20 (đã đổi!)
}
4. Pointer Với Struct
type User struct {
Name string
Age int
}
func updateUser(u *User) {
u.Name = "Updated" // Go tự động dereference
u.Age = 30
}
func main() {
user := User{Name: "Minh", Age: 25}
updateUser(&user)
fmt.Println(user.Name) // Updated
fmt.Println(user.Age) // 30
}
5. Khi Nào Dùng Pointer?
- ✅ Khi cần thay đổi giá trị gốc
- ✅ Khi truyền struct lớn (tránh copy)
- ✅ Khi cần biểu diễn giá trị nil
- ❌ Với kiểu nhỏ (int, bool) - không cần thiết
⚠️ Zero value của pointer:
nil - không trỏ đến đâu cả. Dereference nil sẽ
panic!
📝 Tóm Tắt
- Pointer lưu địa chỉ bộ nhớ
&xlấy địa chỉ,*plấy giá trị- Pass by reference để thay đổi biến gốc
- Zero value pointer:
nil