Hàm (function) là một khối mã lệnh được sử dụng để thực hiện một nhiệm vụ cụ thể. Trong Go, hàm là một phần quan trọng giúp tổ chức mã nguồn, tái sử dụng mã và cải thiện tính rõ ràng của chương trình. Bài viết này sẽ cung cấp một cái nhìn tổng quan chi tiết về hàm trong Go, bao gồm cách khai báo, gọi hàm, các loại tham số, giá trị trả về, và một số ví dụ minh họa cụ thể.
Khai Báo Hàm
Để khai báo một hàm trong Go, chúng ta sử dụng từ khóa func
, theo sau là tên hàm, danh sách tham số (nếu có), kiểu dữ liệu trả về (nếu có), và thân hàm.
Cú pháp:
go
func tên_hàm(danh_sách_tham_số) kiểu_trả_về {
// thân hàm
}
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm không có tham số và không trả về giá trị
func greet() {
fmt.Println("Hello, World!")
}
func main() {
// Gọi hàm greet
greet()
}
Trong ví dụ trên, chúng ta khai báo một hàm greet
không có tham số và không trả về giá trị. Hàm này chỉ đơn giản in ra dòng chữ "Hello, World!".
Gọi Hàm
Để gọi một hàm, chúng ta sử dụng tên hàm theo sau là cặp dấu ngoặc đơn ()
.
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm với tham số
func greet(name string) {
fmt.Printf("Hello, %s!\n", name)
}
func main() {
// Gọi hàm greet với đối số
greet("Alice")
greet("Bob")
}
Trong ví dụ này, hàm greet
nhận một tham số kiểu chuỗi name
và in ra lời chào với tên được truyền vào.
Tham Số Hàm
Tham số là các biến được khai báo trong danh sách tham số của hàm và được sử dụng để nhận giá trị từ các đối số khi hàm được gọi.
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm với hai tham số kiểu int
func add(a int, b int) int {
return a + b
}
func main() {
// Gọi hàm add với hai đối số
sum := add(3, 4)
fmt.Printf("Sum: %d\n", sum)
}
Trong ví dụ này, hàm add
nhận hai tham số kiểu int
và trả về tổng của chúng.
Giá Trị Trả Về
Hàm trong Go có thể trả về một hoặc nhiều giá trị. Để chỉ định kiểu dữ liệu trả về, chúng ta thêm kiểu dữ liệu sau danh sách tham số. Để trả về giá trị từ hàm, chúng ta sử dụng từ khóa return
.
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm trả về một giá trị
func multiply(a int, b int) int {
return a * b
}
func main() {
// Gọi hàm multiply và nhận giá trị trả về
product := multiply(3, 4)
fmt.Printf("Product: %d\n", product)
}
Trong ví dụ này, hàm multiply
nhận hai tham số kiểu int
và trả về tích của chúng.
Trả Về Nhiều Giá Trị
Go cho phép hàm trả về nhiều giá trị. Điều này rất hữu ích trong nhiều tình huống, chẳng hạn như khi cần trả về cả kết quả và lỗi.
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm trả về hai giá trị
func divide(a int, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
func main() {
// Gọi hàm divide và nhận hai giá trị trả về
quotient, err := divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Quotient: %d\n", quotient)
}
// Gọi hàm divide với b = 0
quotient, err = divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Quotient: %d\n", quotient)
}
}
Trong ví dụ này, hàm divide
nhận hai tham số kiểu int
và trả về hai giá trị: thương số và lỗi. Nếu b
bằng 0, hàm trả về lỗi "division by zero".
Hàm Biến Đổi (Variadic Functions)
Hàm biến đổi là hàm có thể nhận một số lượng tham số không xác định. Để khai báo hàm biến đổi, chúng ta sử dụng dấu ba chấm ...
trước kiểu dữ liệu của tham số cuối cùng.
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm biến đổi
func sum(numbers ...int) int {
total := 0
for _, number := range numbers {
total += number
}
return total
}
func main() {
// Gọi hàm sum với số lượng tham số khác nhau
fmt.Printf("Sum: %d\n", sum(1, 2, 3))
fmt.Printf("Sum: %d\n", sum(4, 5, 6, 7, 8))
}
Trong ví dụ này, hàm sum
nhận một số lượng tham số không xác định kiểu int
và trả về tổng của chúng.
Hàm Ẩn Danh (Anonymous Functions)
Hàm ẩn danh là hàm không có tên và có thể được khai báo và gọi ngay lập tức. Hàm ẩn danh thường được sử dụng như các hàm callback hoặc trong các biểu thức ngắn gọn.
Ví dụ:
go
package main
import "fmt"
func main() {
// Khai báo và gọi hàm ẩn danh
func(message string) {
fmt.Println(message)
}("Hello, Anonymous Function!")
}
Trong ví dụ này, chúng ta khai báo và gọi một hàm ẩn danh để in ra thông điệp "Hello, Anonymous Function!".
Hàm Trả Về Hàm (Higher-Order Functions)
Go cho phép hàm trả về một hàm khác. Điều này rất hữu ích trong các tình huống như tạo các hàm callback hoặc các hàm có thể cấu hình.
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm trả về một hàm khác
func multiplier(factor int) func(int) int {
return func(x int) int {
return x * factor
}
}
func main() {
// Tạo hàm nhân đôi và nhân ba
double := multiplier(2)
triple := multiplier(3)
// Gọi các hàm nhân đôi và nhân ba
fmt.Printf("Double 5: %d\n", double(5))
fmt.Printf("Triple 5: %d\n", triple(5))
}
Trong ví dụ này, hàm multiplier
nhận một tham số factor
và trả về một hàm nhân x
với factor
.
Hàm với Tham Số Con Trỏ (Pointer Parameters)
Go hỗ trợ truyền tham số bằng con trỏ, cho phép hàm thay đổi giá trị của biến gốc.
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm với tham số con trỏ
func increment(x *int) {
*x++
}
func main() {
var a int = 10
fmt.Printf("Before increment: %d\n", a)
// Gọi hàm increment với địa chỉ của a
increment(&a)
fmt.Printf("After increment: %d\n", a)
}
Trong ví dụ này, hàm increment
nhận một con trỏ tới int
và tăng giá trị của biến gốc lên 1.
Hàm với Giá Trị Trả Về Được Đặt Tên (Named Return Values)
Go cho phép đặt tên cho các giá trị trả về trong khai báo hàm. Điều này giúp mã nguồn trở nên rõ ràng hơn và cho phép sử dụng "naked return".
Ví dụ:
go
package main
import "fmt"
// Khai báo hàm với giá trị trả về được đặt tên
func rectangleArea(length, width int) (area int) {
area = length * width
return
}
func main() {
// Gọi hàm rectangleArea
fmt.Printf("Area: %d\n", rectangleArea(5, 3))
}
Trong ví dụ này, hàm rectangleArea
trả về diện tích của hình chữ nhật và giá trị trả về được đặt tên là area
.
Kết Luận
Hàm là một phần quan trọng trong lập trình Go, giúp tổ chức mã nguồn, tái sử dụng mã và cải thiện tính rõ ràng của chương trình. Bài viết này đã cung cấp một cái nhìn tổng quan chi tiết về hàm trong Go, bao gồm cách khai báo, gọi hàm, các loại tham số, giá trị trả về, và một số ví dụ minh họa cụ thể. Hiểu rõ về hàm sẽ giúp bạn viết mã Go hiệu quả và dễ bảo trì hơn.