命名函數的返回參數有什麼好處?爲什麼要命名返回參數?
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