我的函数返回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
}
我找到的唯一解决方法是使用*Card
而不是Card
,在出现错误时将其设为nil
或将其指向实际Card
当没有错误发生时,那是非常笨拙的。
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
是一个命名的返回值,我可以在不初始化的情况下使用它。它以自己的方式归零,我并不在乎,因为调用函数不应该使用这个值。
答案 0 :(得分:13)
func canFail() (card Card, err error) {
return card, errors.New("not yet implemented")
}
我认为这是你的第三个例子,也很好。理解的规则是当函数返回错误时,除非文档另有说明,否则不能依赖其他返回值来获得有意义的值。所以在这里返回一个可能没有意义的结构值是很好的。
答案 1 :(得分:5)
例如,
type Card struct {
}
func canFail() (card Card, err error) {
return Card{}, errors.New("not yet implemented")
}
答案 2 :(得分:5)
func canFail() (card Card, err error) {
if somethingWrong {
err = errors.New("Not yet implemented")
return
}
if foo {
card = baz
return
}
...
// or
return Card{Ace, Spades}, nil
}
答案 3 :(得分:2)
作为返回结构的一种可能的替代方法,您可以考虑让调用者分配它并将函数设置为params。
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
}
如果您不方便假装Go支持C ++样式引用,您还应该检查card
是否为nil
。
答案 4 :(得分:1)
对于我来说,我更喜欢您的第二个选择。
func canFail() (card *Card, err error) {
return nil, errors.New("not yet implemented");
}
这样,您可以确保在发生错误时,canFail()
调用者将无法使用card
,因为它为空。我们无法确保调用者将首先检查错误。
答案 5 :(得分:1)
peterSO 答案是最接近的,但它不是我会使用的。我认为这 最好:
func canFail() (Card, error) {
return Card{}, errors.New("not yet implemented")
}
首先,它不使用指针只是为了使用 nil
返回。我认为
这是一个巧妙的技巧,但除非您确实需要 struct
作为指针
(出于修改或其他原因),然后返回一个值更好。我也不
认为应该命名返回值,除非您正在使用它们,例如
这个:
func canFail() (card Card, err error) {
return
}
这是有问题的,原因有两个。首先,你并不总是会在
在这种情况下,您可以简单地将返回值设为任何变量
是在那个时候。其次,如果你有一个更大的功能,你将无法使用
更深层次的赤裸裸的回报,因为你会得到可变的阴影错误。
最后,使用 Card{}
而不是 nil
或 card
更冗长,但更好
传达你正在做的事情。如果您使用其中任何一个:
return
return card, err
如果没有上下文就不清楚函数是否成功,而这个:
return Card{}, err
很明显该函数失败了。它与您将使用的模式相同 原始类型:
return false, err
return 0, err
return '\x00', err
return "", err
return []byte{}, err
https://github.com/golang/go/wiki/CodeReviewComments#pass-values
答案 6 :(得分:0)
我建议您使用指针而不是类型,因为如果遇到任何错误,它会创建该类型的空对象。而是返回类型的指针,并在出现错误时返回nil。
{{1}}