Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Error handling 返回结构或错误的惯用方法是什么?_Error Handling_Go_Zero - Fatal编程技术网

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