简明的nil检查struct field指针?

时间:2016-05-04 23:58:36

标签: pointers go struct null comparison

说我有这个结构:

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 = 42
case f.Qux == nil:
    return errors.New("Missing 'qux'")
}

(或通过一系列if陈述等...)

我知道我可以将所有nil比较分隔为一个逗号case,但每个nil检查都会有不同的回报。

我的问题:是否有一种不那么冗长的方式进行零检查?

1 个答案:

答案 0 :(得分:1)

向您提出一个问题:您想要获得的详细程度如何?因为你想在不同的条件下做不同的事情(不同的领域是lll () { ls -l ... --color=always ... $@ | less -R ; } )。您的代码包含这些不同的东西和不同的条件。除此之外"多余"在您的代码中只包含nilswitch个关键字。你想把它们留下来吗?因为其余部分不是“多余的”,所以它们是必需的。

另请注意,即使没有case(与其他语言不同),在Go case中也不会失败,所以在上面的例子中breakf.Baz ,您将其设置为nil并且不会检查42(因此不会返回f.Qux),但如果error不是 - f.Baznilf.Qux,将返回nil。我知道它只是一个例子,但这是要记住的事情。如果您使用error,则应首先处理error!或者使用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

Go Playground上尝试这些。