说我有这个结构:
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
检查都会有不同的回报。
我的问题:是否有一种不那么冗长的方式进行零检查?
答案 0 :(得分:1)
向您提出一个问题:您想要获得的详细程度如何?因为你想在不同的条件下做不同的事情(不同的领域是lll () { ls -l ... --color=always ... $@ | less -R ; }
)。您的代码包含这些不同的东西和不同的条件。除此之外"多余"在您的代码中只包含nil
和switch
个关键字。你想把它们留下来吗?因为其余部分不是“多余的”,所以它们是必需的。
另请注意,即使没有case
(与其他语言不同),在Go case
中也不会失败,所以在上面的例子中break
是f.Baz
,您将其设置为nil
并且不会检查42
(因此不会返回f.Qux
),但如果error
不是 - f.Baz
且nil
为f.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上尝试这些。