当前位置: 首页 > 面试题库 >

避免检查错误是否为零重复?

汪高岑
2023-03-14
问题内容

我目前正在学习go,我的一些代码如下所示:

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 ...

这在我看来有点不对劲,因为错误检查占用了大多数行。有没有更好的方法来进行错误处理?我是否可以通过一些重构来避免这种情况?

更新:
感谢您的所有答案。请注意,在我的示例中,doB取决于a,doC取决于b,依此类推。因此,大多数建议的重构在这种情况下不起作用。还有其他建议吗?


问题答案:

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

以下是一些常见的问题:

1-还不错

这是对这些抱怨的非常普遍的反应。实际上,您的代码中有几行额外的代码实际上并不是那么糟糕。这只是廉价的打字,在阅读方面非常容易处理。

2-这实际上是一件好事

这是基于这样的事实,即键入和读取这些额外的行可以很好地提醒您,实际上您的逻辑可能会在此时逃逸,并且您必须撤消放置在其前几行中的所有资源管理。通常将其与异常进行比较,这会以隐式方式破坏逻辑流,迫使开发人员始终牢记隐藏的错误路径。前一段时间,我在这里写了一篇更深入的评论。

3-使用紧急/恢复

在某些特定情况下,您可以通过使用panic已知类型来避免某些工作,然后recover在您的程序包代码问世之前立即使用,将其转换为适当的错误,然后返回该错误。这种技术最常用于展开递归逻辑,例如(un)元帅。

我个人尽量不要滥用过多,因为我与第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)在下面的评论中很好地提醒的那样,ifGo中的语句在条件之前接受一个简单的语句。因此,您可以执行以下操作:

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

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

在某些特定情况下,我宁愿避免以这种方式嵌入该语句,只是为了清晰起见而使其独立存在,但这是一个微妙的个人事情。



 类似资料:
  • 问题内容: 我有一个URL表,并且我不需要任何重复的URL。如何使用PHP / MySQL检查表中是否已存在给定URL? 问题答案: 如果您不想重复,可以执行以下操作: 添加唯一性约束 使用“ REPLACE ”或“ INSERT … ON DUPLICATE KEY UPDATE ”语法 如果多个用户可以向DB中插入数据,@ Jeremy Ruten建议的方法可能会 导致错误 :执行检查后,某人

  • 我想知道是否有可能在Java中“避免”空检查,以下面的代码为例: 它必须检查4次,否则代码将失败。 是否可以将语句转换为只有在没有NullPointerException时才执行的一行式语句?当出现异常时,该行应该被忽略。 这里我不是在谈论一个通用的语言特性,我是在谈论一个只有当您明确决定这样做时才会上交的特性。 例如:将是建议代码的一个片段。 在Java可能发生这样的事情吗? 如果不可能的话,在

  • 在Java,有没有一种方法可以避免在调用的每个级别上嵌套null检查,以确保沿途没有阻止下一次调用的null。有没有一个优雅的方法来做这件事? 例如: Objone.ObjTwo.ObjTree.ObjFour.ObjF

  • 问题内容: 我有此错误信息: 消息8134,级别16,状态1,第1行除以零错误。 编写SQL代码的最佳方法是什么,这样我就再也看不到此错误消息了? 我可以执行以下任一操作: 添加一个where子句,这样我的除数永远不会为零 或者 我可以添加一个case语句,以便对零进行特殊处理。 使用子句的最佳方法是吗? 有没有更好的方法,或者如何执行? 问题答案: 为了避免出现“被零除”错误,我们对此进行了如下

  • 问题内容: 我有部分填充的对象数组,当我遍历它们时,我尝试检查所选对象是否在我对其进行其他处理之前。但是,即使通过似乎也检查过它。也将包括所有元素。您如何检查数组中的元素?例如,以下代码将为我抛出一个NPE。 问题答案: 您的活动比您说的要多。我从您的示例中运行了以下扩展测试: 并获得了预期的输出: 您是否可能尝试检查someArray [index]的长度?

  • 我有一个调用外部API的Java程序(在下面的代码中),有时我想避免调用此API,而是返回预先构造的响应(由生成)。 所以,我在大多数方法中都复制了这种构造: 有哪些选项可以避免在任何地方重复这个try/catch块?重要的是,如果抛出异常或返回null,则必须调用。