为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕桂英3389331 2021-06-14 05:04:57
我目前正在学习 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,依此类推。因此,大多数建议的重构在这种情况下不起作用。还有什么建议吗?
查看完整描述

2 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

这是一个常见的抱怨,对此有多种答案。


以下是一些常见的:


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 在下面的评论中很好地提醒的那样,ifGo 中的语句在条件之前接受一个简单的语句。所以你可以这样做:


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

    return err

}

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


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


查看完整回答
反对 回复 2021-06-28
?
跃然一笑

TA贡献1826条经验 获得超6个赞

您可以使用命名返回参数来缩短一些事情

func doStuff() (result string, err error) {

    a, err := doA()

    if err != nil {

        return

    }

    b, err := doB(a)

    if err != nil {

        return

    }

    result, err = doC(b)

    if err != nil {

        return

    }

    return

}

在你用 Go 编程一段时间后,你会意识到必须检查每个函数的错误会让你思考如果该函数出错,它实际上意味着什么,以及你应该如何处理它。


查看完整回答
反对 回复 2021-06-28
  • 2 回答
  • 0 关注
  • 197 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信