Go 函式的多回傳值與具名回傳值
型別後置的寫法讓函式簽章多了兩個特色:連續同型別的參數可以合併寫,以及回傳值可以有多個、甚至可以取名字。
參數簡寫
func add(x int, y int) int {} // 完整寫法
func add(x, y int) int {} // 連續同型別可以只寫最後一個多回傳值
func swap(x, y string) (string, string) {
return y, x
}
a, b := swap("hello", "world") // world hello多回傳值是 Go 的招牌:v, ok := m[k]、v, err := f() 都是它,所以 Go 不需要 exception 也不需要 tuple 型別。
具名回傳值與 naked return
回傳值可以先取名字,等於在函式頂部宣告了這些變數,之後 return 後面什麼都不寫(naked return)就會把它們回傳出去:
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // 等同 return x, y
}⚠️ 會降低可讀性:讀到 return 那一行時看不出回傳了什麼,得往回找變數的最後一次賦值。函式一長就很容易誤讀,所以慣例是只在短函式裡用。
具名回傳值真正有價值的場合是搭配 defer 修改回傳值(例如在 defer 裡包裝 error),那時名字是必要的——除此之外,把回傳值寫清楚在 return 後面通常更好。