避免检查错误是否为零重复? [英] Avoid checking if error is nil repetition?

查看:111
本文介绍了避免检查错误是否为零重复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  a,err:= doA() 
if err!= nil {
return nil,err
}
b,err:= doB(a)
if err!= nil {
return nil,err
}
c,err:= doC(b)
if err!= nil {
return nil,err
}
...等等...

这对我来说看起来有些不对,因为错误检查占用了大部分行。有没有更好的方法来做错误处理?我可以通过一些重构来避免这种情况吗?



更新:谢谢所有答案。请注意,在我的例子中,doB依赖于a,doC依赖于b等等。因此,大多数建议的重构在这种情况下不起作用。任何其他建议?

解决方案

这是一个常见的投诉,并且有几个答案。 b

以下是一些常见的:

1 - 没有那么糟糕



这是对这些投诉非常普遍的反应。事实上,在代码中有几行代码实际上并不是那么糟糕。这只是一种便宜的打字,在阅读时很容易处理。



2 - 它实际上是一件好事



这是基于这样一个事实,即打字和阅读这些额外的行很好地提醒您,实际上您的逻辑可能会在那个时候逃脱,并且您必须撤销任何资源管理你已经放在它前面的行中。这通常会与异常进行比较,这可能会以隐式方式打破逻辑流,迫使开发人员始终考虑隐藏的错误路径。前段时间,我写了一篇关于这里的更深入的评论。

3 - 使用恐慌/恢复

通过使用已知类型的 panic ,然后在包代码熄灭之前使用 recover 来避免某些工作进入世界,将其转化为适当的错误,然后返回。这种技术最常见的用于展开递归逻辑,例如(un)marshalers。



我个人尽量不要滥用这个,因为我与点更紧密相关1和2。

4 - 重新编码一下



在这种情况下,您可以稍微重组逻辑以避免重复。



作为一个简单的例子,这个:

 err:= doA()
if err!= nil {
return err
}
err:= doB()
if err!= nil {
return err
}
return nil

也可以组织为:

  err:= doA()
if err!= nil {
return err
}
return doB()

5 - 使用命名结果



有些人使用命名结果去除return语句中的err变量。尽管如此,我建议不要这样做,因为它可以节省很少的代码,降低代码的清晰度,并且在纾困返回语句之前定义了一个或多个结果时,逻辑容易出现细微问题。



6 - 在if条件之前使用语句

正如Tom Wilde在评论中提醒的那样如果语句在<在条件之前接受一个简单的声明。所以你可以这样做:

  if err:= doA(); err!= nil {
return err
}

这是一个很好的Go习惯用法,并经常使用。



在某些特定情况下,为避免出于清晰目的,我宁愿避免以这种方式嵌入语句,但为此是一个微妙和私人的事情。


I'm currently learning go and some of my code looks like this:

a, err := doA()
if err != nil {
  return nil, err
}
b, err := doB(a)
if err != nil {
  return nil, err
}
c, err := doC(b)
if err != nil {
  return nil, err
}
... and so on ...

This looks kinda wrong to me because the error checking takes most of the lines. Is there a better way to do error handling? Can I maybe avoid this with some refactoring?

UPDATE: Thank you for all the answers. Please note that in my example doB depends on a, doC depends on b and so on. Therefore most suggested refactorings don't work in this case. Any other suggestion?

解决方案

This is a common complaint, and there are several answers to it.

Here are a few common ones:

1 - It's not so bad

This is a very common reaction to these complaints. The fact you have a few extra lines of code in your code is not in fact so bad. It's just a bit of cheap typing, and very easy to handle when on the reading side.

2 - It's actually a good thing

This is based on the fact that typing and reading these extra lines is a very good reminder that in fact your logic might escape at that point, and you have to undo any resource management that you've put in place in the lines preceding it. This is usually brought up in comparison with exceptions, which can break the flow of logic in an implicit way, forcing the developer to always have the hidden error path in mind instead. Some time ago I wrote a more in-depth rant about this here.

3 - Use panic/recover

In some specific circumstances, you may avoid some of that work by using panic with a known type, and then using recover right before your package code goes out into the world, transforming it into a proper error and returning that instead. This technique is seen most commonly to unroll recursive logic such as (un)marshalers.

I personally try hard to not abuse this too much, because I correlate more closely with points 1 and 2.

4 - Reorganize the code a bit

In some circumstances, you can reorganize the logic slightly to avoid the repetition.

As a trivial example, this:

err := doA()
if err != nil {
    return err
}
err := doB()
if err != nil {
    return err
}
return nil

can also be organized as:

err := doA()
if err != nil {
    return err
}
return doB()

5 - Use named results

Some people use named results to strip out the err variable from the return statement. I'd recommend against doing that, though, because it saves very little, reduces the clarity of the code, and makes the logic prone to subtle issues when one or more results get defined before the bail-out return statement.

6 - Use the statement before the if condition

As Tom Wilde well reminded in the comment below, if statements in Go accept a simple statement before the condition. So you can do this:

if err := doA(); err != nil {
    return err
}

This is a fine Go idiom, and used often.

In some specific cases, I prefer to avoid embedding the statement in this fashion just to make it stand on its own for clarity purposes, but this is a subtle and personal thing.

这篇关于避免检查错误是否为零重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆