大意没闪系列一:for 循环中直接 return

本贴最后更新于 275 天前,其中的信息可能已经沧海桑田

hello,大家好,欢迎来到银之庭。我是 Z,一个普通的程序员。

《大意没闪》系列是记录我工作中遇到的低级但常见的代码 bug 的系列文章,这是本系列的第一篇,主题是:在 for 循环中直接 return。

1. bug 示例

核心的 bug 伪代码如下所示,就像标题说的,在 for 循环中直接 return 了:

for item in items:
    // do something
    // ...

    if item.isXxx:
        return 

如果 for 循环中的逻辑比较简单,这种 bug 还是比较容易看出来的,但如果 for 循环中的逻辑很复杂,比如达到了几十上百行,有各种业务逻辑判断时,我们就很容易陷入到单个元素的处理逻辑中,忘了我们处在一个 for 循环里,心里想着“如果这个元素是这样的,就应该直接返回,不用后续处理了“,然后写出上面的直接 return 的代码(没错,说的就是我)。

2. bug 影响

这种 bug 会导致列表中后面的部分元素得不到执行,如果有一个 Kafka consumer,它会批量拉取消息,然后用一个 for 循环执行,但 for 循环中有这个 bug,这时候从业务上看起来就像 consumer 漏消息了一样(没错,我就是这个情况,线上出问题后最开始还没想到是代码的问题,以为是公司 Kafka 服务有问题,查了半天)。

3. 如何避免

说实话,这种 bug 属于如果你写的时候没注意,事后很难主动发现的 bug。首先,code review 几乎不可能发现,因为 reviewer 几乎不会看这么仔细,尤其是 for 循环内部逻辑很复杂后,他也很容易陷入单一元素的处理逻辑中去;其次,代码扫描工具也几乎不会扫描这种问题,因为这实际上是个业务逻辑,有可能在 for 循环中直接 return 是符合逻辑的,所以代码扫描工具最多只会报个 warn,但众所周知,程序员向来忽略 warn;最后,这种 bug 上线后,即使线上出了问题,想要找到这个罪魁祸首,也会费一番力气,可能还得靠“灵光一闪“这种东西(没错,说的还是我)。

这种 bug 几乎只能依靠写代码的程序员提前意识到这个问题,在 for 循环中时刻注意 continuebreakreturn 的使用。所以,我决定写这篇以及《大意没闪》这一系列文章,主要目的就是给我,以及所有看到这篇文章的同学提个醒,希望我们以后都不要再犯这样的错误了。

  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    75 引用 • 1719 回帖 • 3 关注
  • 大意没闪
    1 引用 • 1 回帖

广告 我要投放

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...