這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
github: https://github.com/ZhangzheBJUT/blog/blob/master/nil.md
一 介面與nil
前面講解了go語言中介面的基本使用方法,下面將說一說nil在介面中的使用。
從上面一節我們知道在底層,interface作為兩個成員實現:一個類型和一個值。該值被稱為介面的動態值, 它是一個任意的具體值,而該介面的類型則為該值的類型。對於 int 值3, 一個介面值示意性地包含(int, 3)。
只有在內部值和類型都未設定時(nil, nil),一個介面的值才為 nil。特別是,一個 nil 介面將總是擁有一個 nil 類型。若我們在一個介面值中儲存一個 int 類型的指標,則內部類型將為 int,無論該指標的值是什麼,這樣的介面值會是非 nil 的,即使在該指標的內部值為 nil,形如(*int, nil)。
下面是一個錯誤的錯誤返回方式:
func returnsError() error { var p *MyError = nil if bad() { p = ErrBad } return p // Will always return a non-nil error.}
這裡 p 返回的是一個有效值(非nil),值為 nil。
因此,下面判斷錯誤的代碼會有問題:
func main() { if err := returnsError(); err != nil { panic(nil) }}
上面的if判斷永遠為真,因為resturnsError返回的值的類型不為nil。
針對 returnsError 的問題,可以這樣處理(不建議的方式):
func main() { if err := returnsError(); err.(*MyError) != nil { panic(nil) }}
在判斷前先將err轉型為*MyError,然後再判斷err的值。 類似的C語言Null 字元串可以這樣判斷:
bool IsEmptyStr(const char* str) { return !(str && str[0] != '\0');}
但是Go語言中標準的錯誤返回方式不是returnsError這樣。 下面是改進的returnsError:
func returnsError() error { var p *MyError = nil if bad() { return nil } return p // Will always return a non-nil error.}
二 小結
在處理錯誤傳回值的時候,一定要將正常的錯誤值轉換為 nil。
參考: http://golang.org/doc/faq#nil_error