为了账号安全,请及时绑定邮箱和手机立即绑定

简洁的 nil 检查结构字段指针?

简洁的 nil 检查结构字段指针?

Go
米琪卡哇伊 2022-01-10 10:51:35
假设我有这个结构:type Foo struct {    Bar        *string          `json:"bar"`    Baz        *int64           `json:"baz,omitempty"`    Qux        *string          `json:"qux"`    Quux       string           `json:"quux"`}解组 json 后,我检查 nil ,如下所示:switch {case f.Bar == nil:    return errors.New("Missing 'bar'")case f.Baz == nil:    f.Baz = 42case f.Qux == nil:    return errors.New("Missing 'qux'")}(或通过一系列if语句等...)我知道我可以将所有nil比较放在一个逗号分隔中case,但每张nil支票都会有不同的回报。我的问题:是否有一种不那么冗长的方法来进行 nil 检查?
查看完整描述

1 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

向您提出的一个问题:您想获得多少的冗长?因为你想在不同的条件下做不同的事情(不同的领域是nil)。您的代码包含这些不同的内容和不同的条件。除此之外,代码中“冗余”的只是switchandcase关键字。你想把他们排除在外吗?因为其余的不是“冗余的”,所以它们是必需的。


另请注意,在 Go 中case即使没有 a 也不会失败break(与其他语言不同),因此在上面的示例中 if f.Bazis nil,您将其设置为42并且f.Qux不会被检查(因此error将返回no ),但 iff.Baz是 non - niland f.Quxis nil,error将返回一个。我知道这只是一个例子,但请记住这一点。error如果你使用 a ,你应该先处理s switch!或者使用if语句,然后无论字段检查的顺序如何,都会检测并返回错误。


您的代码switch干净高效。如果你想让它不那么冗长,可读性(和性能)会受到影响。


您可以使用辅助函数来检查指针值是否为nil:


func n(i interface{}) bool {

    v := reflect.ValueOf(i)

    return v.Kind() == reflect.Ptr && v.IsNil()

}

并使用它:


func check(f *Foo) error {

    switch {

    case n(f.Bar):

        return errors.New("Missing 'bar'")

    case n(f.Qux):

        return errors.New("Missing 'qux'")

    case n(f.Baz):

        x := int64(42)

        f.Baz = &x

    }

    return nil

}

或使用if语句:


func check2(f *Foo) error {

    if n(f.Bar) {

        return errors.New("Missing 'bar'")

    }

    if n(f.Qux) {

        return errors.New("Missing 'qux'")

    }

    if n(f.Baz) {

        x := int64(42)

        f.Baz = &x

    }

    return nil

}


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 153 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信