1. 介绍
Effective go定义:
The return or result “parameters” of a Go function can be given names and used as regular variables, just like the incoming parameters. When named, they are initialized to the zero values for their types when the function begins; if the function executes a return statement with no arguments, the current values of the result parameters are used as the returned values.
稍微翻译下:
- Go 函数“命名返回值”可以看作是一般的变量,使用和函数传入参数类似
- 在函数开始时将它们初始化为对应类型的零值;
- 如果函数执行不带参数的返回语句(即:只有一个
return
语句),则使用"命名返回参数"的当前值作为返回值。
1.1 声明形式
- 不带 “命名返回值”
func function_name(Parameter-list) (Return_type) {
// function body.....
}
- 带有“命名返回值”
func function_name(Parameter-list) (result_parameter1 data-_type, result_parameter2 data_type, ….){
// function body…..
return
}
例子
// 不带 “命名返回值”
func calculator(a, b int) (int, int) {
mul := a * b
div := a / b
return mul, div
}
// 带有“命名返回值”
func calculator(a, b int) (mul int, div int) {
mul = a * b
div = a / b
return
}
2. 原理
可以理解为“命名返回值”刚开始进行默认初始化
- 基本数据类型为对应类型的
0值
- 指针类型为
nil
效果等价于 使用进行var
声明变量
var param_name data_type
补充
布尔类型的零值(初始值)为false
,数值类型的零值为0
,字符串类型的零值为空字符串""
,而指针、切片、映射、通道、函数和接口的零值则是nil
。
演示
package main
import "fmt"
type Student struct {
name string
age int
}
func testFunc() (a int, b float32, c string, d *int, e Student, f *Student) {
fmt.Printf("a:%v\n", a)
fmt.Printf("b:%v\n", b)
fmt.Printf("c:%v\n", c)
fmt.Printf("d:%v\n", d)
fmt.Printf("e:%v\n", e)
fmt.Printf("f:%v", f)
return
}
func main() {
testFunc()
}
输出
a:0
b:0
c:
d:<nil>
e:{
0}
f:<nil>
3. 优点
- 可以让代码更短、更清晰,可读性更高
- 函数调用者可以更清晰的看到函数返回值。 如开发时,不同层级的代码间相互调用, “命名返回值”可以让开发人员更容易理解函数的返回值
- 不需要自己额外定义返回值,只需要修改需要修改的值即可
4. 注意事项
4.1 “命名返回值”不能重复定义
- 使用
var
重复定义
错误信息提示
- 使用
:=
重复定义
错误信息提示:
no new variables on left side of :=
注意,:=
和上面的var
错误信息提示不同, 如果:=
左侧有新的变量声明,则:=
是可以包含 “命名返回值”的,不过是给“命名返回值”赋值。
例子:
package main
import "fmt"
// 带有“命名返回值”
func calculator(a, b int) (mul int, div int) {
x, mul := 99, 5 // 此时修改了mul的值
fmt.Println("x = :", x) // x = 99
mul = a * b
div = a / b
return
}
func main() {
fmt.Println(calculator(4, 2)) // 输出 8, 2
}
4.2 return时可重新指定返回值
package main
import "fmt"
func calculator(a, b int) (mul int, div int) {
mul = a * b
div = a / b
// 重新指定返回值
return 12, 34
}
func main() {
mul, div := calculator(6, 2)
fmt.Printf("mul:%d, div:%d", mul, div) // 输出 12, 34
}
4.3 命名返回值和未命名返回值不能混合使用
5. 参考文章
https://deepinout.com/go/go-tutorials/t_naming-the-return-values-of-a-function-in-golang.html
https://go.dev/doc/effective_go
https://blog.csdn.net/weixin_40068281/article/details/89166253