英文:
Is it a problem to pass a single error to errors.Join?
问题
Go 1.20引入了errors.Join
函数,可以包装多个错误。调用此函数并只传入一个错误是否会有任何问题?
例如,这篇文章建议不要对可写文件使用defer f.Close()
的习惯用法,因为这样会静默忽略Close
返回的任何错误。相反,它建议使用命名返回值err
来允许Close
的返回值传播,除非这样做会覆盖之前的错误:
defer func() {
cerr := f.Close()
if err == nil {
err = cerr
}
}()
在这种情况下,使用errors.Join
似乎更正确:
defer func() {
cerr := f.Close()
err = errors.Join(err, cerr)
}()
如果err
和cerr
都不为nil
,这将返回两个错误。如果两者都为nil
,它将返回nil
。
然而,如果一个为nil
,另一个为非nil
,errors.Join
将不仅返回非nil
错误,还会返回一个包装在errors.joinError
中的错误。像这样包装错误是否会引起任何问题?特别是如果调用堆栈中的多个函数都使用这种方法,那么单个错误可能会出现在多个层级的包装中。
英文:
Go 1.20 introduces the errors.Join
function that can wrap multiple errors. Are there any issues with calling this function and only passing in a single error?
For example, this article recommends against using the defer f.Close()
idiom for writable files, because that would silently ignore any error returned by Close
. Instead, it suggests using a named return value err
to allow the return value of Close
to be be propagated - unless doing so would overwrite an earlier error:
defer func() {
cerr := f.Close()
if err == nil {
err = cerr
}
}()
It seems more correct to use errors.Join
in this scenario:
defer func() {
cerr := f.Close()
err = errors.Join(err, cerr)
}()
If both err
and cerr
are non-nil, this will now return both errors. If both are nil
, it will return nil
.
However, if one is nil
and the other non-nil
, errors.Join
will not just return the non-nil
error but an errors.joinError
wrapper around it. Could wrapping an error like this cause any problems? Especially if several functions in the call stack use this approach, so a single error could end up within multiple layers of wrapper?
答案1
得分: 2
如果errors.JoinError
只有一个非nil错误,那仍然是一个连接错误,并且errors.As
和errors.Is
函数会按预期工作。这在连接错误的嵌套级别无论如何都是正确的。
唯一的潜在问题是如果存在以下代码:
err := someFunc()
if err == io.EOF {
...
}
那么这将失败。这段代码必须重写以使用errors.Is
。
英文:
If errors.JoinError
has only one non-nil error, that is still a join-error, and errors.As
and errors.Is
functions work as expected. This is correct no matter the level of nesting of joined errors.
The only potential problem would be if there is code like:
err:=someFunc()
if err==io.EOF {
...
}
then this will fail. This code has to be rewritten to use errors.Is
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论