
1.出乎意料的比較結果
首先看一段代碼:
func main() {
s := "redigo: nil returned"
err1 := errors.New(s)
err2 := errors.New(s)
if err1 == err2 {
fmt.Println("err is equal")
} else {
fmt.Println("err is not equal")
}
}
對兩個相同字串生成的 error 進行比較,結果如何呢?很多人可能和我一樣,認為兩個 error 變數是相等的,但實際上卻不相等,輸出結果:
err is not equal
為什么呢?這就需要我們知道介面變數相等比較到底比較了那些東西,
一個變數的兩大基本屬性就是"型別+值",介面變數也不例外,所以我們在比較介面變數是否相等時,如果"型別+值"二者都相等,那么才相等,
2.型別不等值相等
首先看一個介面變數所表示的值相等但型別不等的例子,
func main() {
var ifc1 interface{} = int(1)
var ifc2 interface{} = int64(1)
if ifc1 == ifc2 {
fmt.Println("err is equal")
} else {
fmt.Println("err is not equal")
}
fmt.Printf("%T %T %v %v\n", ifc1, ifc2, ifc1, ifc2)
}
定義了兩個空介面型別變數 ifc1 和 ifc2,二者代表的真實值均是 1,但是型別卻不相等,所以二等并不相等,
運行輸出:
err is not equal
int int64 1 1
3.型別相等值不等
再看一個介面變數所表示的型別相等但值不等的例子,
func main() {
var ifc1 interface{} = int(1)
var ifc2 interface{} = int(2)
if ifc1 == ifc2 {
fmt.Println("err is equal")
} else {
fmt.Println("err is not equal")
}
fmt.Printf("%T %T %v %v\n", ifc1, ifc2, ifc1, ifc2)
}
因為兩個空介面型別變數 ifc1 和 ifc2 代表的值不等,盡管二者所代表的型別均是 int,但是二者仍是不等的,
err is not equal
int int 1 2
4.回首掏
再回到最開始兩個 error 變數相比較,既然不相等,那么說明其代表的值或型別至少有一個不相等,
眼睛看到的,并不一定是真相,盡管我們傳的字串是同一個,最終賦給 error 介面變數的值是 errors.New() 函式回傳的東西,我們在 Golang 標準庫 errors/errors.go 中可以找到 errors.New() 的定義,
// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
可以看到 errors.New() 每次回傳的是結構體 errorString 變數的地址,每一次回傳的都是新值,所以介面變數 err1 和 err2 存盤的值并不相等,所以二者并不相等,
5.小結
當我們判斷兩個介面變數知否相等時,要注意介面變數所表示的具體型別和值均相等時才會相等,不要被表象迷惑,寫出錯誤的代碼,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/275848.html
標籤:區塊鏈
下一篇:創建Vue專案以及報錯解決
