命名函数的返回参数会带来什么好处?
func namedReturn(i int) (ret int) {
ret = i
i += 2
return
}
func anonReturn(i int) int {
ret := i
i += 2
return ret
}
答案 0 :(得分:37)
命名它们有一些好处:
还有一些缺点,主要是通过声明一个同名变量很容易意外地影响它们。
Effective Go有section on named result parameters:
Go函数的返回或结果“参数”可以给出名称 并用作常规变量,就像传入的参数一样。什么时候 命名时,它们被初始化为其类型的零值 功能开始;如果函数执行带有的return语句 没有参数,结果参数的当前值用作 返回的值。
名称不是强制性的,但可以缩短代码 更清楚:他们是文件。如果我们将nextInt的结果命名为它 变得明显,返回int是哪个。
func nextInt(b []byte, pos int) (value, nextPos int) {
[...]
答案 1 :(得分:20)
命名返回变量的另一个特殊用途是由延迟函数文字捕获。一个简单的例子:
package main
import (
"errors"
"fmt"
)
func main() {
fmt.Println(f())
}
var harmlessError = errors.New("you should worry!")
func f() (err error) {
defer func() {
if err == harmlessError {
err = nil
}
}()
return harmlessError
}
输出为<nil>
。在更实际的场景中,延迟函数可以处理恐慌,并且除了错误结果之外还可以修改其他返回值。然而,共同的魔力是,延迟文字有可能在f终止之后修改f 的返回值,无论是正常还是恐慌。
答案 2 :(得分:3)
至少在两种情况下有用:
每当您必须声明要返回的变量时。 E.g。
func someFunc() (int, error) {
var r int
var e error
ok := someOtherFunc(&r) // contrived, I admit
if !ok {
return r, someError()
}
return r, nil
}
VS
func someFunc() (r int, e error) {
ok := someOtherFunc(&r)
if !ok {
e = someError()
}
return
}
随着通过函数的执行路径数量的增加,这变得更加重要。
当您记录返回值并希望按名称引用它们时。 godoc
认为返回变量是函数签名的一部分。
答案 3 :(得分:2)
例如,命名的返回参数可以通过名称来访问。
func foo() (a, b, c T) {
// ...
if qux {
b = bar()
}
// ...
return
}
这不容易复制没有命名的返回参数。必须引入与命名返回参数基本相同的功能的局部变量:
func foo() (T, T, T) {
var a, b, c T
// ...
if qux {
b = bar()
}
// ...
return a, b, c
}
所以直接允许它更容易。
此外,它们也可以在另一个方向访问:
func foo() (a, b, c T) {
// ...
if a > c {
b = bar()
}
// ...
return
}
等