軌道
/
Go
Go
/
課程大綱
/
多重回傳值
多重

多重回傳值 在 Go

{other: "%{count} 個練習"}

關於 多重回傳值

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

逗號 ok 慣用語

雙值賦值模式也出現在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。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟