dq23171 2017-07-04 07:51
浏览 28
已采纳

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

If I have a struct containing a nil pointer of type A, using reflect.DeepEqual to check if that property is nil will result in false, which strikes me as odd behaviour.

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"

Specifically, I am marshaling a JSON object into a struct, where I would like to test that a specific property is nil when the corresponding JSON structure does not contain it. If reflect.DeepEqual is not the way to go, how should I do this?

  • 写回答

1条回答 默认 最新

  • dreamy1992 2017-07-04 08:07
    关注

    Everything you pass to reflect.DeepEqual() is wrapped in an interface{} value (if it's not already that):

    func DeepEqual(x, y interface{}) bool
    

    interface{} values will be compared, where the first parameter value is not nil, only the value wrapped in it.

    An interface value is represented as a (type; value) pair. The first value you pass to reflect.DeepEqual() is a pair of (type; value) being (*Obj, nil), and the 2nd value is nil. They are not equal. The second value lacks type information.

    If you compare it to a "typed" nil, it will be true:

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

    See this example:

    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)))
    

    Output (try it on the Go Playground):

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

    See this question for a deeper insight:

    Hiding nil values, understanding why golang fails here

    If you want to check if the value wrapped inside a non-nil interface is nil, you can use reflection: reflect.Value.IsNil().

    For more details see: Why interface type doesn't provide an "IsNil" method?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分