go 函数命名返回值(Named result parameters)

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 
}

image.png

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重复定义

错误信息提示
image.png

  • 使用 :=重复定义

错误信息提示: no new variables on left side of :=
image.png

注意:=和上面的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 命名返回值和未命名返回值不能混合使用

image.png

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

猜你喜欢

转载自blog.csdn.net/VariatioZbw/article/details/131524616
今日推荐