命名函数的返回参数有什么好处?为什么要命名返回参数?
func namedReturn(i int) (ret int) {
ret = i
i += 2
return
}
func anonReturn(i int) int {
ret := i
i += 2
return ret
}
命名函数的返回参数有什么好处?为什么要命名返回参数?
func namedReturn(i int) (ret int) {
ret = i
i += 2
return
}
func anonReturn(i int) int {
ret := i
i += 2
return ret
}
有命名他们一些好处:
也有缺点,主要是很容易通过声明一个相同名称的变量来隐藏它们。
Effective Go有section on named result parameters。
这是非常有用的,至少两种情况:
每当你必须声明你要回归变量。例如。
func someFunc() (int, error) {
var r int
var e error
ok := someOtherFunc(&r) // contrived, I admit
if !ok {
return r, someError()
}
return r, nil
}
与
func someFunc() (r int, e error) {
ok := someOtherFunc(&r)
if !ok {
e = someError()
}
return
}
这得到作为通过函数增加的执行路径的数目更重要。
当您记录返回值并希望按名称引用它们时。 godoc
考虑函数签名的返回变量部分。
例如,名称返回参数可以通过名称访问。
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
}
等等
名为返回变量的另一种特殊的用途是通过递延函数文本被捕获。一个简单的例子:
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 的返回值。
即使err在f()内本地声明,然后被延迟使用,f()也不会以同样的方式工作吗? => func f()(err error){} @sonia – 2015-10-20 11:19:13
要添加到@thomaskappler的答案和那里的讨论(我还没有评论),您可以使用命名结果参数,并在返回中指定变量。这提供了文档的好处,但消除了影子问题。但是,它确实消除了>如果您有多个返回站点,则如果您更改函数的返回值,则不需要全部更改它们,因为它只会说“返回”。效益。 – darkwing 2017-05-25 20:10:18