2017-07-04 53 views
1

如果我有一個包含nil類型爲A的指針的結構,使用reflect.DeepEqual來檢查該屬性是否爲nil將導致false,這使我感到奇怪的行爲。結構不深的nil指針等於nil?

type Container struct { 
    O *Obj 
} 

type Obj struct { 
    Message string 
} 

var c Container 
eq := reflect.DeepEqual(c.O, nil) 
fmt.Printf("O value: %v, is nil: %t", c.O, eq) 
// Prints: "O value: <nil>, is nil: false" 

具體而言,我編組JSON對象成一個結構,其中,我想測試特定屬性是nil當相應的JSON結構不包含它。如果reflect.DeepEqual不是要走的路,我該怎麼做?您傳遞給reflect.DeepEqual()

+0

你是對的..讓看文檔:https://golang.org/pkg/reflect/#DeepEqual。在第一段中回答你的問題 - 不同類型的值永遠不會相等。其餘的答案在這裏https://golang.org/doc/faq#nil_error – lofcek

回答

1

一切都被包裝在一個interface{}值(如果它不是已經說):

func DeepEqual(x, y interface{}) bool 

interface{}值進行比較,其中第一個參數值nil,只值包裹在裏面。

接口值表示爲(type; value)對。您傳遞給reflect.DeepEqual()的第一個值是一對(type; value)(*Obj, nil),第二個值爲nil。他們不平等。第二個值缺少類型信息。

如果你把它比作一個 「類型」 nil,這將是true

reflect.DeepEqual(c.O, (*Obj)(nil)) // This is true 

見這個例子:

fmt.Println("c.O:", c.O) 
fmt.Println("c.O == nil:", c.O == nil) 
fmt.Println("c.O deep equal to nil:", reflect.DeepEqual(c.O, nil)) 
fmt.Println("c.O deep equal to (*Obj)(nil):", reflect.DeepEqual(c.O, (*Obj)(nil))) 

輸出(嘗試在Go Playground):

c.O: <nil> 
c.O == nil: true 
c.O deep equal to nil: false 
c.O deep equal to (*Obj)(nil): true 

查看此問題以獲取更深入的見解:

Hiding nil values, understanding why golang fails here

如果你想檢查包裹非nil界面中值爲nil,你可以使用反射:reflect.Value.IsNil()

有關詳細信息,請參閱:Why interface type doesn't provide an "IsNil" method?

+0

感謝接口上的鏈接,我今天學到了一些新東西! – Sander