GCTT 出品』在 Go 中使用命名返回变量捕获 panic

这将是一个简短的帖子,灵感来源于 Sean Kelly 十一月份的推特。

我发现了一个在 golang 中使用指定的返回值的原因并且现在我感到潸然泪下。

— Sean Kelly (@StabbyCutyou) 2017年11月15日

其目标是为了记录并说明一种有必要使用到命名返回变量的情况,所以说让我们进入正题。

想象你正在编写一些用了可能 panic 的函数的代码,并且无论什么原因(第三方库,向后兼容,等等)你都不能改变那些函数。

你仍然需要用到那个函数,不过如果它发生异常,而你想要捕获到这个 panic 并将它作为一个 error 返回,那么你应该写一些类似这样的代码:

在 Go Playground 上执行它 - https://play.golang.org/p/wzkjKGqFPL

之后你 go run 了你的代码然而…这是什么?你的 error 是 nil 值,甚至是在代码发生异常的时候。这并不是我们想要的!

为什么会发生这种情况?

虽然最初看起来我们的代码返回的是我们在函数开始时创建的 ,但事实上,我们的程序永远不会到达这一行代码。这意味着它永远不会返回特定的 err 变量,而且在我们的 defer 函数内部改变它,最终会变得毫无意义。

在调用 之后添加一个 ,但在返回之前,确实有助于说明这一点:

在 Go Playground 上执行它 - https://play.golang.org/p/Vk0DYs20eB

我们该如何修复它

为了修复这个问题,我们可以简单地使用命名返回变量。

在 Go Playground 上执行它 - https://play.golang.org/p/bqGOroPjQJ

最终的代码看起来非常的相似,不过通过命名我们的返回变量,当我们声明这个函数时,我们的程序将会立刻返回这个 变量,即使我们从未触碰到 函数的末尾的返回语句。由于这个细微的差别,现在我们可以更改被我们 的函数中的 变量,并且成功地捕获到这个 panic。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180719G0P9C700?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券