函数和方法
函数定义
基本语法
go
func functionName(param1 type1, param2 type2) returnType {
// 函数体
return value
}示例
go
// 简单函数
func add(a int, b int) int {
return a + b
}
// 相同类型参数可以简写
func add(a, b int) int {
return a + b
}
// 无返回值
func printMessage(msg string) {
fmt.Println(msg)
}
// 多个返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为0")
}
return a / b, nil
}多返回值
Go 语言的函数可以返回多个值,这是 Go 语言的特色之一:
go
// 返回两个值
func swap(a, b string) (string, string) {
return b, a
}
// 命名返回值
func calculate(a, b int) (sum int, product int) {
sum = a + b
product = a * b
return // 自动返回命名变量
}
// 使用示例
x, y := swap("hello", "world")
sum, prod := calculate(3, 4)可变参数
使用 ... 表示可变参数:
go
// 可变参数必须是最后一个参数
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
// 调用
result := sum(1, 2, 3, 4, 5)
result = sum(1, 2, 3)
// 传递切片
nums := []int{1, 2, 3}
result = sum(nums...)函数作为值
在 Go 中,函数是一等公民,可以作为值传递:
go
// 函数类型
type Operation func(int, int) int
func add(a, b int) int {
return a + b
}
func multiply(a, b int) int {
return a * b
}
// 函数作为参数
func calculate(a, b int, op Operation) int {
return op(a, b)
}
// 使用
result := calculate(3, 4, add)
result = calculate(3, 4, multiply)匿名函数和闭包
匿名函数
go
// 立即执行
func() {
fmt.Println("匿名函数")
}()
// 赋值给变量
add := func(a, b int) int {
return a + b
}
result := add(3, 4)闭包
闭包可以访问外部作用域的变量:
go
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
// 使用
c := counter()
fmt.Println(c()) // 1
fmt.Println(c()) // 2
fmt.Println(c()) // 3defer 语句
defer 用于延迟执行函数,常用于资源清理:
go
func readFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close() // 函数返回前执行
// 处理文件
return nil
}
// 多个 defer 按 LIFO 顺序执行
func example() {
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// 输出: 3, 2, 1
}方法
方法是带有接收者的函数。
值接收者
go
type Rectangle struct {
Width float64
Height float64
}
// 值接收者方法
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// 使用
rect := Rectangle{Width: 10, Height: 5}
area := rect.Area()指针接收者
go
// 指针接收者方法(可以修改接收者)
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
// 使用
rect := Rectangle{Width: 10, Height: 5}
rect.Scale(2) // rect 被修改选择值接收者还是指针接收者?
- 值接收者:当方法不需要修改接收者,或者接收者是小型结构体时使用
- 指针接收者:当方法需要修改接收者,或者接收者是大型结构体时使用
方法集
go
type Person struct {
Name string
Age int
}
// 值接收者方法
func (p Person) GetName() string {
return p.Name
}
// 指针接收者方法
func (p *Person) SetAge(age int) {
p.Age = age
}
// 都可以通过值和指针调用
person := Person{Name: "Alice", Age: 30}
person.GetName() // OK
(&person).GetName() // OK
person.SetAge(31) // OK (自动取地址)
(&person).SetAge(31) // OK函数和方法示例
go
package main
import "fmt"
// 普通函数
func greet(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
// 多返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为0")
}
return a / b, nil
}
// 可变参数
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
// 结构体和方法
type Calculator struct {
result int
}
func (c *Calculator) Add(n int) {
c.result += n
}
func (c Calculator) GetResult() int {
return c.result
}
func main() {
// 函数调用
msg := greet("Go")
fmt.Println(msg)
// 多返回值
result, err := divide(10, 2)
if err != nil {
fmt.Println("错误:", err)
} else {
fmt.Println("结果:", result)
}
// 可变参数
total := sum(1, 2, 3, 4, 5)
fmt.Println("总和:", total)
// 方法调用
calc := Calculator{}
calc.Add(10)
calc.Add(20)
fmt.Println("计算结果:", calc.GetResult())
}下一步
接下来我们将学习:
