如果我的结构包含nil类型为的指针A,则reflect.DeepEqual用于检查该属性是否nil会导致false,这使我感到奇怪。
nil
A
reflect.DeepEqual
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不是要走的路,我应该怎么做?
您传递给的所有内容都reflect.DeepEqual()包装在一个interface{}值中(如果还没有的话):
reflect.DeepEqual()
interface{}
func DeepEqual(x, y interface{}) bool
interface{}将比较值,其中第一个参数值 不是nil,仅包装在其中的值。
接口值表示为一(type; value)对。您传递给的第一个值reflect.DeepEqual()是一对(type; value)存在(*Obj, nil),第二个值是nil。他们不平等。第二个值缺少类型信息。
(type; value)
(*Obj, nil)
如果将其与“类型化”进行比较nil,则将为true:
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()。