GO語言————5.2 測試多返回值函式的錯誤
5.2 測試多返回值函式的錯誤
Go 語言的函式經常使用兩個返回值來表示執行是否成功:返回某個值以及 true 表示成功;返回零值(或 nil)和 false 表示失敗(第 4.4 節)。當不使用 true 或 false 的時候,也可以使用一個 error 型別的變數來代替作為第二個返回值:成功執行的話,error 的值為 nil,否則就會包含相應的錯誤資訊(Go 語言中的錯誤型別為 error: var err error
,我們將會在第 13 章進行更多地討論)。這樣一來,就很明顯需要用一個 if 語句來測試執行結果;由於其符號的原因,這樣的形式又稱之為 comma,ok 模式(pattern)。
在第 4.7 節的程式 string_conversion.go
中,函式 strconv.Atoi
的作用是將一個字串轉換為一個整數。之前我們忽略了相關的錯誤檢查:
anInt, _ = strconv.Atoi(origStr)
如果 origStr 不能被轉換為整數,anInt 的值會變成 0 而 _
無視了錯誤,程式會繼續執行。
這樣做是非常不好的:程式應該在最接近的位置檢查所有相關的錯誤,至少需要暗示使用者有錯誤發生並對函式進行返回,甚至中斷程式。
我們在第二個版本中對程式碼進行了改進:
示例 1:
示例 5.3 string_conversion2.go
package main
import (
"fmt"
"strconv"
)
func main() {
var orig string = "ABC"
// var an int
var newS string
// var err error
fmt.Printf("The size of ints is: %d\n", strconv.IntSize)
// anInt, err = strconv.Atoi(origStr)
an, err := strconv.Atoi(orig)
if err != nil {
fmt.Printf("orig %s is not an integer - exiting with error\n", orig)
return
}
fmt.Printf("The integer is %d\n", an)
an = an + 5
newS = strconv.Itoa(an)
fmt.Printf("The new string is: %s\n", newS)
}
這是測試 err 變數是否包含一個真正的錯誤(if err != nil
)的習慣用法。如果確實存在錯誤,則會列印相應的錯誤資訊然後通過 return 提前結束函式的執行。我們還可以使用攜帶返回值的 return 形式,例如 return err
。這樣一來,函式的呼叫者就可以檢查函式執行過程中是否存在錯誤了。
習慣用法
value, err := pack1.Function1(param1)
if err != nil {
fmt.Printf("An error occured in pack1.Function1 with parameter %v", param1)
return err
}
// 未發生錯誤,繼續執行:
由於本例的函式呼叫者屬於 main 函式,所以程式會直接停止執行。
如果我們想要在錯誤發生的同時終止程式的執行,我們可以使用 os
包的 Exit
函式:
習慣用法
if err != nil {
fmt.Printf("Program stopping with error %v", err)
os.Exit(1)
}
(此處的退出程式碼 1 可以使用外部指令碼獲取到)
有時候,你會發現這種習慣用法被連續重複地使用在某段程式碼中。
當沒有錯誤發生時,程式碼繼續執行就是唯一要做的事情,所以 if 語句塊後面不需要使用 else 分支。
示例 2:我們嘗試通過 os.Open
方法開啟一個名為 name
的只讀檔案:
f, err := os.Open(name)
if err != nil {
return err
}
doSomething(f) // 當沒有錯誤發生時,檔案物件被傳入到某個函式中
doSomething
練習 5.1 嘗試改寫 string_conversion2.go 中的程式碼,要求使用 :=
方法來對 err 進行賦值,哪些地方可以被修改?
示例 3:可以將錯誤的獲取放置在 if 語句的初始化部分:
習慣用法
if err := file.Chmod(0664); err != nil {
fmt.Println(err)
return err
}
示例 4:或者將 ok-pattern 的獲取放置在 if 語句的初始化部分,然後進行判斷:
習慣用法
if value, ok := readData(); ok {
…
}
注意事項
如果您像下面一樣,沒有為多返回值的函式準備足夠的變數來存放結果:
func mySqrt(f float64) (v float64, ok bool) {
if f < 0 { return } // error case
return math.Sqrt(f),true
}
func main() {
t := mySqrt(25.0)
fmt.Println(t)
}
您會得到一個編譯錯誤:multiple-value mySqrt() in single-value context
。
正確的做法是:
t, ok := mySqrt(25.0)
if ok { fmt.Println(t) }
注意事項 2
當您將字串轉換為整數時,且確定轉換一定能夠成功時,可以將 Atoi
函式進行一層忽略錯誤的封裝:
func atoi (s string) (n int) {
n, _ = strconv.Atoi(s)
return
}
實際上,fmt
包(第 4.4.3 節)最簡單的列印函式也有 2 個返回值:
count, err := fmt.Println(x) // number of bytes printed, nil or 0, error
當列印到控制檯時,可以將該函式返回的錯誤忽略;但當輸出到檔案流、網路流等具有不確定因素的輸出物件時,應該始終檢查是否有錯誤發生(另見練習 6.1b)。
相關文章
- Go 函式多返回值錯誤處理與error 型別介紹Go函式Error型別
- GO語言————6.2 函式引數與返回值Go函式
- Go 語言函式Go函式
- GO語言————6.1 函式Go函式
- Go 語言 -make函式Go函式
- GO語言————6.9 應用閉包:將函式作為返回值Go函式
- go語言學習-函式Go函式
- Go語言基礎-錯誤處理Go
- Go語言錯誤處理機制Go
- 函式 -- 就要學習 Go 語言函式Go
- GO語言————6.5 內建函式Go函式
- GO語言————6.6 遞迴函式Go遞迴函式
- APP 多語言測試APP
- go語言初學者常見錯誤Go
- 5.go語言函式提綱Go函式
- C語言中函式的返回值C語言函式
- 面試官:來說一說Go語言的函式呼叫慣例面試Go函式
- 【Go】Go語言學習筆記-2-函式Go筆記函式
- 從錯誤處理看 Rust 的語言和 Go 語言的設計RustGo
- 小白學習Golang(六)Go語言函式Golang函式
- go語言入門之-函式和方法Go函式
- GO語言入門 - (六)函式和方法Go函式
- 兄弟連go教程(15)函式 - 錯誤處理Go函式
- Go語言(golang)的錯誤(error)處理的推薦方案GolangError
- 清華尹成帶你實戰GO案例(32)Go 函式多返回值Go函式
- Lumen 表單校驗配置 validation 的中文 (多語言) 錯誤語
- Go 語言基準測試入門Go
- Go Quiz: 從Go面試題看函式命名返回值的注意事項(超過80%的人都回答錯了)GoUI面試題函式
- 兄弟連go教程(13)函式 返回值Go函式
- GO語言————6.7 將函式作為引數Go函式
- 【Go語言學習】匿名函式與閉包Go函式
- C語言的函式C語言函式
- 介面測試讀取 Excel 中引數返回值全部錯誤Excel
- Go 語言區塊鏈測試實踐指南(一):GO單元測試Go區塊鏈
- Go 錯誤處理新思路?用左側函式和表示式Go函式
- GO語言————6.11 計算函式執行時間Go函式
- Go語言入門系列(六)之再探函式Go函式
- Go語言Slice作為函式引數詳解Go函式