Error handling 返回结构或错误的惯用方法是什么?
我有一个函数,它要么返回Error handling 返回结构或错误的惯用方法是什么?,error-handling,go,zero,Error Handling,Go,Zero,我有一个函数,它要么返回卡,这是结构类型,要么返回错误 问题是,当发生错误时,如何从函数返回零对于结构无效,并且我的卡类型没有有效的零值 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
卡
,这是结构
类型,要么返回错误
问题是,当发生错误时,如何从函数返回<代码>零对于结构无效,并且我的卡
类型没有有效的零值
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
}
我找到的唯一解决方法是使用*卡而不是卡,当出现错误时,将其设置为nil
,或者在没有错误发生时将其设置为实际的卡,但这相当笨拙
func canFail() (card *Card, err error) {
return nil, errors.New("not yet implemented");
}
有更好的办法吗
编辑:我找到了另一种方法,但不知道这是惯用的还是好的风格
func canFail() (card Card, err error) {
return card, errors.New("not yet implemented")
}
由于card
是一个命名的返回值,因此我可以使用它而无需初始化它。它以自己的方式归零,我并不在意,因为调用函数不应该使用这个值。例如
type Card struct {
}
func canFail() (card Card, err error) {
return Card{}, errors.New("not yet implemented")
}
我觉得这个,你的第三个例子,也不错。理解的规则是,当函数返回错误时,除非文档另有明确解释,否则不能依赖其他返回值来获得有意义的值。因此,返回一个可能无意义的结构值是很好的。作为返回结构的一种可能的替代方法,您可以考虑让调用方分配它和函数集参数。
func canFail(card *Card) (err error) {
if someCondition {
// set one property
card.Suit = Diamond
// set all at once
*card = Card{Ace, Spade}
} else {
err = errors.New("something went wrong")
}
return
}
如果你不习惯假装支持C++风格的引用,你也应该检查<代码>卡<代码> > <代码> nIL/CONT>
对我来说,我更喜欢你的第二个选择
func canFail() (card *Card, err error) {
return nil, errors.New("not yet implemented");
}
这样,您就可以确保当发生错误时,canFail()
调用者将无法使用卡,因为它是零。我们无法确保呼叫者会首先检查错误。彼得索的答案是最接近的,但这不是我会使用的答案。我觉得这个
最好是:
首先,它不使用指针,只是为了使用nil
返回。我想
这是一个巧妙的技巧,但除非您确实需要struct
作为指针
(出于修改或其他原因),则返回值更好。我也不知道
认为返回值应该命名,除非您正在使用它们,比如
这:
这是有问题的,原因有二。首先,你不可能总是在家
在这种情况下,您可以简单地让返回值为该变量的任何值
那是在当时。第二,如果你有一个更大的功能,你将无法使用
在更深层次的裸回归,因为你会得到可变的阴影错误。
最后,使用Card{}
而不是nil
或Card
更详细,但更好
传达你正在做的事情。如果您使用以下任一选项:
return
return card, err
如果没有上下文,功能是否成功就不清楚,而这:
return Card{}, err
很明显,函数失败了。这和你会使用的模式是一样的
基本类型:
return false, err
return 0, err
return '\x00', err
return "", err
return []byte{}, err
在本例中,返回值甚至不必命名。(您可能仍然希望它们被命名为其他原因,或者您可能会觉得没有杂乱的名称,函数更清晰。)阅读问题和我的答案。这是一个稍后要实现的存根函数——空的struct
和“尚未实现”
消息。由于我们不知道将使用什么代码来实现该函数,唯一安全的方法是返回定义良好的值,无论以后使用什么代码。谢谢,这在语义上接近于我的上一个解决方案,尽管syntaxIt返回指针的习惯用法有点不同,因此可以使用nil。当您不使用命名返回值时,它有助于避免错误并使早期返回更容易。虽然能够返回nil而不是指针肯定很方便,但我不会仅出于这个原因而使用指针。返回的非零错误足以告诉您不要使用“卡”中的数据。您应该检查错误,而不是值。否则返回错误就没有什么意义了。。。
func canFail() (card Card, err error) {
return
}
return
return card, err
return Card{}, err
return false, err
return 0, err
return '\x00', err
return "", err
return []byte{}, err