小编典典

指向struct的nil指针不深等于nil吗?

go

如果我的结构包含nil类型为的指针A,则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对象编组到一个结构中,在该结构中,我想测试一个特定的属性是nil当相应的JSON结构不包含该属性时。如果reflect.DeepEqual不是要走的路,我应该怎么做?


阅读 264

收藏
2020-07-02

共1个答案

小编典典

您传递给的所有内容都reflect.DeepEqual()包装在一个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

请参阅以下问题以获得更深入的了解:

隐藏nil值,了解golang为什么会失败

如果要检查包装在非nil接口中的值是否为nil,则可以使用反射:reflect.Value.IsNil()

2020-07-02