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
}值接收者和指针接收者
| 类型 | 特点 | 适合场景 |
|---|---|---|
| 值接收者 | 调用时复制一份对象 | 对象小、不需要修改字段 |
| 指针接收者 | 传递对象地址 | 对象大、需要修改字段、避免复制 |
实际项目中,如果一个类型有方法使用指针接收者,通常建议该类型其他方法也保持指针接收者,风格更统一。
实战建议
- 函数要短,专注做一件事。
- 错误必须显式处理,不要忽略
err。 - 多返回值不要滥用,返回太多字段时可以定义结构体。
- 复杂函数避免裸
return。 - 方法是否使用指针接收者要保持一致。
下一步可以继续看 结构体与接口。
