这是一个常见的抱怨,有几个答案。
以下是一些常见的:
1 - 还不错
这是对这些投诉的一种非常普遍的反应。您的代码中有几行额外的代码实际上并没有那么糟糕。这只是一些廉价的打字,在阅读方面很容易处理。
2 - 这实际上是一件好事
这是基于这样一个事实,即键入和阅读这些额外的行是一个很好的提醒,实际上您的逻辑可能会在此时逃脱,并且您必须撤消您在其前面的行中实施的任何资源管理。与异常相比,这通常会被提出,异常会以隐含的方式破坏逻辑流程,从而迫使开发人员始终牢记隐藏的错误路径。前段时间我在这里写了一篇更深入的咆哮。
3 - 使用恐慌/恢复
在某些特定情况下,您可以通过使用已知类型来避免其中的一些工作panic
,然后recover
在您的包代码发布之前使用,将其转换为适当的错误并返回它。这种技术最常用于展开递归逻辑,例如 (un) marshaler。
我个人尽量不过度滥用这一点,因为我与第 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 变量。不过,我建议不要这样做,因为它节省的资源很少,降低了代码的清晰度,并且当在 bail-out return 语句之前定义了一个或多个结果时,逻辑容易出现微妙的问题。
6 - 在 if 条件之前使用语句
正如 Tom Wilde 在下面的评论中提醒的那样,if
Go 中的语句在条件之前接受一个简单的语句。所以你可以这样做:
if err := doA(); err != nil {
return err
}
这是一个很好的 Go 习惯用法,并且经常使用。
在某些特定情况下,我宁愿避免以这种方式嵌入声明,只是为了让它独立起来,以便清楚起见,但这是一件微妙而个人化的事情。