IT 论文精读 · PAPER 37

Go To Statement Considered Harmful(GOTO 有害论)

Edsger W. Dijkstra · Communications of the ACM · 1968

EN →

这篇论文干了什么?

1968 年,荷兰计算机科学家 Edsger Dijkstra 给一本学术期刊写了一封两页的短信,标题是《GOTO 语句有害》。信里没有算法、没有公式,却成了软件史上最有名的文章之一,直接改写了「代码该怎么写」这件事。今天你写的 if / while / for、以及几乎每种语言都劝你少用甚至干脆删掉的 goto——源头就是这封信。

先说 goto 是什么

早年的程序像一张写满编号行的清单,goto 是一条命令:「别往下读了,直接跳到第 87 行接着执行」。它能往前跳、往后跳、跳进跳出任何地方。方便是真方便,但一个稍大的程序里塞满这种跳转,读起来就像一团缠死的耳机线——业内管这叫「面条代码」

Dijkstra 看破的那件怪事

他点破了一件很微妙的事:我们读代码是从上往下、一行行看的(静态的文字),可程序真正跑起来是在时间里一步步走的(动态的过程)。写程序的人脑子里得始终对上这两件事——「我读到的这一行,对应程序跑到哪一步」。而他有个关于人的观察:人天生擅长看懂静态的排列,却很不擅长在脑中想象一个随时间演化的过程。所以好代码的关键,是让静态的文字尽量像动态执行的一张地图

那个点子

goto 恰恰把这张地图撕烂了。打个比方:读一本普通的书,一个书签就能标记「我读到哪了」;可要是这本书每一页都写着「现在跳去翻第几页」、跳来跳去,那个书签就没意义了——你光看书签,根本说不清故事进行到哪、之前发生过什么。

Dijkstra 的主张是:只用三种「不乱跳」的积木——顺着往下(顺序)、二选一(if 分支)、重复做(循环)——就足以写出任何程序;而这样写出来的代码,永远能用「读到第几行 +(如果在循环里)转了几圈」这样一个清清楚楚的书签,标出程序此刻走到哪。文字重新变回了可靠的地图。

带来了什么

这封信点燃了「结构化编程」运动。此后新语言纷纷把 if/while/for 做成一等公民、把 goto 打入冷宫;「代码要让人读得懂」第一次被摆到和「能跑」同等重要的位置。今天你几乎不会在正经代码里见到 goto,多半就拜这封信所赐。诚实说一句:后来 Knuth 等人指出,少数情形(比如出错时一跳跳出好几层循环)用一次跳转反而更清楚——所以主流做法是「极力少用」,而非「绝对禁止」。

一句话记住

代码是静态的文字,执行是动态的过程;人脑擅长前者、拙于后者。goto 能任意乱跳,让「读到哪」对不上「跑到哪」,文字不再是执行的地图。改用顺序 / 分支 / 循环三种积木,就永远能用一个清楚的书签标出程序此刻的位置——代码于是可读、可查、可信。

想看「进度坐标」的精确论证、控制流对比图与后续争论? → 切到精读版