Skip to content

Golang函数

函数是 Go 程序组织逻辑的基本单元。Go 没有类方法那种复杂继承体系,但通过函数、方法、接口组合出非常清晰的代码结构。

函数基本格式

go
func add(a int, b int) int {
    return a + b
}

如果多个参数类型相同,可以合并类型声明。

go
func add(a, b int) int {
    return a + b
}

多返回值

Go 支持多个返回值,最常见的是返回结果和错误。

go
func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("除数不能为 0")
    }
    return a / b, nil
}

调用方应显式处理错误:

go
result, err := divide(10, 2)
if err != nil {
    return err
}
fmt.Println(result)

错误处理流程

mermaid
flowchart TD
    A[调用函数] --> B[函数返回 result 和 err]
    B --> C{err 是否为 nil?}
    C -->|否| D[处理错误并返回]
    C -->|是| E[继续使用 result]

命名返回值

Go 允许给返回值命名。

go
func sum(a, b int) (result int) {
    result = a + b
    return
}

命名返回值适合返回值含义很明确的场景。过度使用裸 return 会降低可读性,复杂函数中建议显式返回。

可变参数

可变参数使用 ... 表示。

go
func total(nums ...int) int {
    sum := 0
    for _, num := range nums {
        sum += num
    }
    return sum
}

调用:

go
total(1, 2, 3)

nums := []int{1, 2, 3}
total(nums...)

函数作为值

函数可以作为变量、参数和返回值。

go
func calculate(a, b int, fn func(int, int) int) int {
    return fn(a, b)
}

这使得 Go 可以比较自然地实现回调、策略选择和中间件链。

匿名函数和闭包

匿名函数没有函数名,可以直接执行,也可以赋值给变量。

go
fn := func(name string) {
    fmt.Println("hello", name)
}
fn("go")

闭包可以引用外层变量。

go
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}
mermaid
flowchart TD
    A[外层函数创建局部变量] --> B[返回内部函数]
    B --> C[内部函数继续引用外层变量]
    C --> D[形成闭包]

方法

方法是带接收者的函数。

go
type User struct {
    Name string
}

func (u User) SayHello() {
    fmt.Println("hello", u.Name)
}

如果方法需要修改结构体字段,应使用指针接收者。

go
func (u *User) Rename(name string) {
    u.Name = name
}

值接收者和指针接收者

类型特点适合场景
值接收者调用时复制一份对象对象小、不需要修改字段
指针接收者传递对象地址对象大、需要修改字段、避免复制

实际项目中,如果一个类型有方法使用指针接收者,通常建议该类型其他方法也保持指针接收者,风格更统一。

实战建议

  1. 函数要短,专注做一件事。
  2. 错误必须显式处理,不要忽略 err
  3. 多返回值不要滥用,返回太多字段时可以定义结构体。
  4. 复杂函数避免裸 return
  5. 方法是否使用指针接收者要保持一致。

下一步可以继续看 结构体与接口