1. Khái niệm cơ bản về func
Trong Golang, func
được dùng để khai báo một hàm. Hàm là một tập hợp các câu lệnh được gom nhóm lại để thực thi một nhiệm vụ cụ thể.
1.1 Khai báo và sử dụng hàm
Cú pháp cơ bản:
func functionName(params) (return type) {
// Logic của hàm
return value
}
Ví dụ:
package main
import "fmt"
func greet() {
fmt.Println("Xin chào, Golang!")
}
func main() {
greet() // Gọi hàm
}
Giải thích:
func greet()
: Khai báo hàmgreet
không nhận tham số và không trả về giá trị.fmt.Println
: In ra màn hình.
1.2 Hàm với tham số
Hàm có thể nhận tham số đầu vào để xử lý.
Ví dụ:
func greet(name string) {
fmt.Printf("Xin chào, %s!\n", name)
}
func main() {
greet("An") // Gọi hàm với tham số
}
Giải thích:
name string
: Tham sốname
có kiểu dữ liệustring
.%s
: Placeholder để chèn giá trị của chuỗi.
1.3 Hàm với giá trị trả về
Hàm có thể trả về kết quả sau khi thực thi.
Ví dụ:
func add(a int, b int) int {
return a + b
}
func main() {
result := add(3, 5)
fmt.Println("Kết quả:", result)
}
Giải thích:
int
: Kiểu dữ liệu trả về của hàm.return
: Trả về giá trị cho hàm.
2. Các tính năng nâng cao của func
2.1 Giá trị trả về nhiều
Golang hỗ trợ trả về nhiều giá trị từ một hàm.
Ví dụ:
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("không thể chia cho 0")
}
return a / b, nil
}
func main() {
result, err := divide(10, 2)
if err != nil {
fmt.Println("Lỗi:", err)
} else {
fmt.Println("Kết quả:", result)
}
}
Giải thích:
- Hàm
divide
trả về hai giá trị: - Kết quả chia.
- Lỗi nếu
b == 0
.
2.2 Tham số mặc định (biến động số lượng tham số)
Golang không hỗ trợ trực tiếp tham số mặc định, nhưng có thể dùng tham số biến động.
Ví dụ:
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
fmt.Println("Tổng:", sum(1, 2, 3, 4, 5))
}
Giải thích:
...int
: Cho phép truyền một số lượng tham số không cố định.range numbers
: Duyệt qua các tham số.
2.3 Hàm ẩn danh (Anonymous Function)
Hàm có thể được khai báo mà không cần tên.
Ví dụ:
func main() {
greet := func(name string) {
fmt.Printf("Chào %s\n", name)
}
greet("Huy")
}
Giải thích:
func(name string)
: Khai báo hàm ẩn danh.- Gán hàm ẩn danh cho biến
greet
.
2.4 Hàm như tham số
Hàm có thể được truyền như một tham số.
Ví dụ:
func operate(a, b int, op func(int, int) int) int {
return op(a, b)
}
func add(a, b int) int {
return a + b
}
func main() {
result := operate(3, 5, add)
fmt.Println("Kết quả:", result)
}
Giải thích:
op func(int, int) int
: Hàmop
là tham số.- Hàm
add
được truyền vàooperate
.
2.5 Hàm đệ quy (Recursive Function)
Hàm gọi lại chính nó để giải quyết bài toán.
Ví dụ:
func factorial(n int) int {
if n == 0 {
return 1
}
return n * factorial(n-1)
}
func main() {
fmt.Println("Giai thừa của 5 là:", factorial(5))
}
Giải thích:
- Hàm
factorial
gọi lại chính nó để tính giai thừa.
2.6 Hàm method cho struct
Hàm có thể được liên kết với struct
.
Ví dụ:
type User struct {
Name string
}
func (u User) Greet() {
fmt.Printf("Xin chào, tôi là %s!\n", u.Name)
}
func main() {
user := User{Name: "An"}
user.Greet()
}
Giải thích:
func (u User)
:Greet
là phương thức củaUser
.u.Name
: Truy cập trườngName
củastruct
.
2.7 Trì hoãn thực thi với defer
Lệnh defer
sẽ trì hoãn thực thi cho đến khi hàm kết thúc.
Ví dụ:
func main() {
fmt.Println("Bắt đầu")
defer fmt.Println("Kết thúc")
fmt.Println("Đang thực thi")
}
Kết quả:
Bắt đầu
Đang thực thi
Kết thúc
Giải thích:
defer
: Lệnhfmt.Println("Kết thúc")
chỉ được gọi khi hàm kết thúc.
2.8 Hàm Generator
Hàm có thể được sử dụng để tạo các giá trị tuần tự.
Ví dụ:
func generator() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
next := generator()
fmt.Println(next()) // 1
fmt.Println(next()) // 2
fmt.Println(next()) // 3
}
Giải thích:
- Hàm
generator
trả về một hàm ẩn danh. - Biến
count
được lưu trữ trong closure của hàm.
3. Tổng kết
- Bắt đầu với các khái niệm cơ bản như khai báo, truyền tham số và giá trị trả về.
- Tìm hiểu nâng cao với giá trị trả về nhiều, hàm ẩn danh, và
defer
. - Sử dụng hàm như tham số, đệ quy, và kết hợp với
struct
để xây dựng chương trình phức tạp.
Với các ví dụ trên, bạn đã sẵn sàng sử dụng func
một cách linh hoạt và hiệu quả trong các dự án Go!