在go中,返回结构或错误的惯用方法是什么?

Fab*_*ien 13 error-handling zero go

我有一个函数返回a Card,这是一个struct类型,或一个错误.

问题是,如何在发生错误时从函数返回?nil对结构无效,我的Card类型没有有效的零值.

func canFail() (card Card, err error) {
    // return nil, errors.New("Not yet implemented"); // Fails
    return Card{Ace, Spades}, errors.New("not yet implemented"); // Works, but very ugly
}
Run Code Online (Sandbox Code Playgroud)

我找到的唯一解决方法是使用a *Card而不是a Card,a或者nil在出现错误时使用它,或者Card在没有错误发生时将其指向实际,但这非常笨拙.

func canFail() (card *Card, err error) {
    return nil, errors.New("not yet implemented");
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法 ?

编辑:我找到了另一种方式,但不知道这是否是惯用的甚至是好的风格.

func canFail() (card Card, err error) {
    return card, errors.New("not yet implemented")
}
Run Code Online (Sandbox Code Playgroud)

既然card是一个命名的返回值,我可以在不初始化的情况下使用它.它以自己的方式归零,我并不在乎,因为调用函数不应该使用这个值.

Son*_*nia 13

func canFail() (card Card, err error) {
    return card, errors.New("not yet implemented")
}
Run Code Online (Sandbox Code Playgroud)

我认为这是你的第三个例子,也很好.理解的规则是当函数返回错误时,除非文档另有说明,否则不能依赖其他返回值来获得有意义的值.所以在这里返回一个可能毫无意义的结构值是很好的.

  • 返回一个指针是非常惯用的,所以你可以使用nil.当您不使用命名返回值时,它有助于避免错误并使早期返回更容易. (2认同)
  • 虽然能够返回nil而不是指针当然很方便,但我不会仅出于这个原因而使用指针。返回非零错误的事实足以告诉您不要使用“卡”中的数据。您应该检查错误而不是值。否则根本没有返回任何错误... (2认同)

pet*_*rSO 5

例如,

type Card struct {
}

func canFail() (card Card, err error) {
    return Card{}, errors.New("not yet implemented")
}
Run Code Online (Sandbox Code Playgroud)

  • 在此示例中,甚至不必命名返回值.(你可能仍然希望它们因其他原因而命名,或者你可能觉得这个函数更清晰,没有名字的混乱.) (2认同)