1. 问题
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
return 后面什么都没写,但 x 和 y 确实被返回了。怎么回事?
2. 规则
正常写法是:
func split(sum int) (int, int) {
x := sum * 4 / 9
y := sum - x
return x, y
}
Go 允许给返回值起名字:
func split(sum int) (x, y int) {
// ^^^^^^
// 声明了两个命名返回值
起了名字之后,函数体内可以直接当局部变量用,最后裸写 return,Go 自动把 x、y 带回去。
3. 没赋值就返回零值
命名返回值进来就被初始化成对应类型的零值,你不碰它就原样返回:
func foo() (x int, y string, z bool) {
return
}
// 返回 0, "", false
Go 的变量不存在"未初始化"——声明了就有值。int → 0,string → "",bool → false,指针/slice/map/chan → nil。
4. 裸 return
命名返回值配合裸 return 是这个特性的核心用法:
func divide(a, b int) (result int, err error) {
if b == 0 {
err = errors.New("division by zero")
return // 等价于 return result, err
}
result = a / b
return // 等价于 return result, err
}
短函数里裸 return 确实省事。但函数一长,裸 return 会让读代码的人搞不清到底返回了什么,这时候老老实实写 return result, err 更清楚。
总结
| 写法 | 效果 |
|---|---|
(int, int) | 匿名返回值,必须显式 return x, y |
(x, y int) | 命名返回值,裸 return 也能返回 |
核心用途:短函数 + 多出口时省代码。长函数里别裸 return,省的那几行不值得牺牲可读性。