如果我有一个结构包含类型为A
的nil
指针,使用reflect.DeepEqual
检查该属性是否nil
将导致false
,这让我觉得很奇怪的行为。
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 对象封送到一个结构中,我想在其中测试当相应的 JSON 结构不包含特定属性时是否nil
该属性。如果reflect.DeepEqual
不是要走的路,我该怎么办?
您传递给reflect.DeepEqual()
的所有内容都包装在一个interface{}
值中(如果还没有(:
func DeepEqual(x, y interface{}) bool
将比较interface{}
值,其中第一个参数值不nil
,仅包含包装在其中的值。
接口值表示为(type; value)
对。传递给reflect.DeepEqual()
的第一个值是一对(*Obj, nil)
(type; value)
,第二个值是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
请参阅此问题以获取更深入的见解:
隐藏零值,理解为什么 golang 在这里失败
如果要检查包装在非nil
接口中的值是否nil
,则可以使用 反射:反射。Value.IsNil((.
有关更多详细信息,请参阅:为什么接口类型不提供"IsNil"方法?