NIL == NILはtrueですか?na tum jano na hum ...

3647 ワード


この記事では、使用方法を理解する== オブジェクトの値を比較してください.我々はまた、この演算子の動作が言語のバグのように見えるシナリオを見ますが、それは理解の不足のためです.
以下の例を見てみましょう
var a *string = nil    
var b interface{} = a
fmt.Println("a == nil:", a == nil) // true 
fmt.Println("b == nil:", b == nil) // false 
fmt.Println("a == b:  ", a == b  ) // true
上記の例を理解するには、簡単なものから始めましょう.
var a int = 12
var b int = 12
c:= 12
fmt.Println("a == b :", a == b) // true
fmt.Println("a == c :", a == c) // true
これは非常に明白です.
例をねじりましょう
var a *string = nil
var b interface{} = nil
fmt.Println("a == nil:", a == nil) // true
fmt.Println("b == nil:", b == nil) // true
fmt.Println("a == b:",   a == b) // false (even though the value is
                                           nil for both a and b)
最後の場合を理解するには、深く深く潜入しよう.
Goでは、すべてのポインタ変数には<type, value> すべての変数が型を必要とするという事実は、型が定義されていない変数にNIL値を割り当てることができない理由です.だから我々は書くことができないのですx := nil Xの種類については触れていないので、以下のエラーが出ますuse of untyped nilでは、もう一度私たちの問題を見ましょう
var a *string = nil      // a is <*string, nil>
var b interface{} = nil  // b is <nil, nil>
fmt.Println("a == nil:", a == nil) // true
fmt.Println("b == nil:", b == nil) // true
fmt.Println("a == b:", a == b)    // false <*string,nil>!=<nil, nil>
例変数a 実際に表す<*string, nil> and interface{} デフォルトタイプはnil 変数b is <nil, nil> .
だから私たちが言うときa == b それから、我々は実際に比較している<*string,nil> == <nil, nil> はfalseです.
さあ、メインの例に戻ってください
var a *string = nil     // a is <*string, nil>
var b interface{} = a 
fmt.Println("a ==nil:",a==nil)//true(<*string, nil>==<*string, nil>)
fmt.Println("b == nil:", b == nil) //false (<*string,nil>==<nil,nil>    fmt.Println("a == b:  ", a == b  ) // true
我々がするときa == nil (株)== 演算子は型と値を比較します.ここで、値はLHSとRHSの両方のためにNILです、しかし、Nil - Yang?
NIL(ハードコード値)がオブジェクトと比較されるとき、NILのタイプは比較されるオブジェクトの宣言タイプと同じです.
だからa == nil 私たちはしている<*string, nil> == <*string, nil>の場合b == nil シュン、RHS<nil, nil> の宣言型b はインターフェース{}です.したがって、我々がしたとき
var b interface{} = a
そして、a 変数へbb 現在は<*string, nil> ○○.Hence LHS != RHS注意:var b interface{} = a の宣言型を変更しませんb 変数.

結論


この問題は、以下のコードスニペットのような産業コードで頻繁に起こります.
var resp string
var err error
resp, err = CallFunction()
if err != nil{
   // code inside this if statement will be executed if return type  of CallFunction doesn't match with error
}
func CallFunction() custom.Error{
 // return pointer variable
}
より多くの実験のための遊び場は、ここにありますhttps://play.golang.org/p/BnPPXEs9_Oq
したがって、呼び出し関数の戻り値の型と呼び出し元関数の受信変数の型が一致することを確認する方が良いでしょう.