Go 的函式和方法可以回傳多個值:
func GetCard() (Card, error) { ... }
每個回傳值都必須依序指定給對應的變數,並以逗號分隔:
card, err := GetCard()
賦值語句中的每個位置都會宣告一個變數。
在 Go 中,不允許宣告變數卻不使用。
使用空白識別字_取代變數名稱,就能略過該回傳值。
card, _ := GetCard() // error intentionally ignored
_, err := GetCard() // card ignored, only checking for error
error是內建的介面。
nil錯誤代表沒有發生錯誤;任何非nil的值都代表出了問題。
依照慣例,可能失敗的函式應該把error放在最後一個回傳值。
呼叫方在使用其他回傳值之前,必須先檢查它:
card, err := GetCard()
if err != nil {
// unsafe to use card here
return err
}
// safe to use card here
雙值賦值模式也出現在error處理以外的地方。
map 查詢、型別斷言和通道接收都會使用第二個布林值,依慣例標記為ok,用來表示成功,或資料是否存在:
m := map[string]int{"a": 1}
v, ok := m["a"] // ok is true
v, ok = m["z"] // ok is false
var i interface{} = "hello"
v, ok := i.(string) // ok is true
v, ok = i.(int) // ok is false
v, ok := <-ch // ok is false if ch is closed and empty
回傳值也可以在函式簽章中命名。 這些變數接著就能在函式主體內取用。
func divide(a, b int) (quotient, remainder int) {
quotient = a / b
remainder = a % b
return quotient, remainder
}
具名回傳值能說明每個回傳位置代表什麼意思。 它們也可以搭配裸回傳使用,也就是不寫出任何值的回傳。 裸回傳會隱含地回傳具名變數當下的值:
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
在較長的函式中,裸回傳經常會傷害可讀性,因為看不出究竟回傳了什麼。 除非函式短到整個簽章始終一目了然,否則建議明確寫出回傳值。
想進一步了解,可以參考 Go by Example: Multiple Return Values、Effective Go: Multiple Returns,或是 Tour of Go。