17.1 關於逗號ok模式
在學習本書第二部分和第三部分時,我們經常在一個表達式返回2個參數時使用這種模式:,ok
,第一個參數是一個值或者nil
,第二個參數是true
/false
或者一個錯誤error
。在一個需要賦值的if
條件語句中,使用這種模式去檢測第二個參數值會讓代碼顯得優雅簡潔。這種模式在go語言編碼規範中非常重要。下面總結了所有使用這種模式的例子:
(1)在函數返回時檢測錯誤(參考第5.2小節):
value, err := pack1.Func1(param1)
if err != nil {
fmt.Printf(“Error %s in pack1.Func1 with parameter %v”, err.Error(), param1)
return err
}
// 函數Func1沒有錯誤:
Process(value)
e.g.: os.Open(file) strconv.Atoi(str)
這段代碼中的函數將錯誤返回給它的調用者,當函數執行成功時,返回的錯誤是nil
,所以使用這種寫法:
func SomeFunc() error {
…
if value, err := pack1.Func1(param1); err != nil {
…
return err
}
…
return nil
}
這種模式也常用於通過defer
使程序從panic
中恢復執行(參考第17.2(4)小節)。
要實現簡潔的錯誤檢測代碼,更好的方式是使用閉包,參考第16.10.2小節
(2)檢測映射中是否存在一個鍵值(參考第8.2小節):key1
在映射map1
中是否有值?
if value, isPresent = map1[key1]; isPresent {
Process(value)
}
// key1不存在
…
(3)檢測一個接口類型變量varI
是否包含了類型T
:類型斷言(參考第11.3小節):
if value, ok := varI.(T); ok {
Process(value)
}
// 接口類型varI沒有包含類型T
(4)檢測一個通道ch
是否關閉(參考第14.3小節):
for input := range ch {
Process(input)
}
或者:
for {
if input, open := <-ch; !open {
break // 通道是關閉的
}
Process(input)
}