跳至正文
杂学书库让好奇心有所归处
简体中文

聪明的代码难以修改:柯尼汉定律(Kernighan's Law)

写程序时,总有那么一些时刻,想把代码精简成一行绝妙的写法,或者用别人不易想到的奇巧解法。因为简短而聪明的代码,仿佛是实力的证明。可是几个月后这段代码一出错,往往连写代码的人自己都要盯着看半天,才弄明白当初是什么意思。一针见血地指出这种情形的经验法则,就是“柯尼汉定律(Kernighan's Law)”。

简单来说,柯尼汉定律是指:“找出并修复错误比最初编写代码难一倍,所以如果用尽自己最聪明的方式写代码,你自己就修不了这段代码。”这条把清晰置于聪明之上的建议,至今仍在程序员之间被广泛引用。

本文将依次介绍柯尼汉定律的由来、这句话的含义、围绕这一定律的误解,以及在实际工作中运用这一定律的方法。

柯尼汉定律概念图。图中对比了含义隐晦的复杂代码与分为读取、计算、输出等步骤的代码,说明检查中间运行情况更容易缩小错误原因的范围。“两倍”是强调性的说法,而非测量值。
易读的名称和划分清楚的步骤有助于理解代码的运行并找出错误。这是帮助理解的概念图,“两倍”并非测量值。参考:UCF COP-3402 Introduction,柯尼汉的建议(https://www.cs.ucf.edu/~pappas/teaching/cop3402/spr2026/introduction.html)。

为什么清晰的代码比聪明的代码更长久

来自贝尔实验室的一句话

1970年代的研究所里,一位穿毛衣的程序员坐在老式计算机终端前,旁边放着一摞连续打印纸和文件夹

写下这句话的布莱恩·柯尼汉(Brian Kernighan)是一位出生于加拿大、曾在美国贝尔实验室工作的计算机科学家。他与丹尼斯·里奇(Dennis Ritchie)合著了被誉为C语言教科书的著作,也深度参与了Unix的开发。文本处理语言awk名称中三个字母里的K,也取自他的姓氏;2000年起,他在普林斯顿大学执教。

  • 出处(The Elements of Programming Style):这句话出自他于1974年与同事P. J. 普劳格(P. J. Plauger)合著的《程序设计风格要素》。
  • 修订版(Second Edition):1978年出版了第二版,这句话收录在讨论表达式的第2章。
  • 写作动机(Textbook Examples):两位作者把当时教科书中粗糙的FORTRAN和PL/I代码逐一改写,从中总结出好代码的规则。

书名仿照了著名写作指南《英文写作指南(The Elements of Style)》。正如好文章一样,好代码也应当没有赘余、意思明确——这种观念贯穿全书。


“难一倍”是什么意思

夜里,一位年轻开发者托着下巴坐在笔记本电脑前苦苦思索、寻找错误,桌上放着一只小橡皮鸭和一个茶杯

原文是两句话,意思是:“大家都知道,调试比最初编写程序难一倍。那么,如果你写程序时已经用尽了聪明才智,又该怎么调试它呢?”这里的调试(Debugging),是指找出并修复程序中的错误,也就是bug。

(1)修改比编写更难
写代码时,意图在脑海中清清楚楚;但找错误时,必须反向追查意图与实际运行在哪里出现了偏差。错误恰恰藏在你自认为正确的某个地方,所以更加困难。

(2)聪明才智用尽,就没有余力了
把自己的能力发挥到极限写出的代码,到了比编写难一倍的调试阶段,能力就会不够用。这里的“一倍”并不是精确测量的数值,而是强调差距之大的说法。

(3)所以要写得清晰
结论是:把聪明才智省着用。如果从一开始就写成用自己一半左右的能力就能理解的代码,日后即使出了问题,也有足够的余力找出原因。事实上,同一本书里还收录了“写得清楚些,别太耍聪明(Write clearly – don't be too clever)”这条规则。


围绕这一定律的误解

白色书桌的一边缠着五颜六色的线缆,另一边同样的线缆被整齐地捆好,混乱与整洁形成对比

柯尼汉定律简短而风趣,也因此常被读出与原意不同的意思。

是叫人不要用难的技术吗?

这一定律并不是禁止使用难的技术本身。在确实需要的地方使用精巧的方法,与故意把本可简单解决的问题写得弯弯绕绕,是两回事。需要警惕的,是把难懂的代码当作炫耀资本来写的习惯。尽量减少字符数的游戏“代码高尔夫(Code Golf)”是有趣的头脑训练,但如果把这类代码原样放进实际服务里,负责修改的人就要吃苦头了。

另一种解读:柯尼汉杠杆

瑞典程序员莱纳斯·奥克松(Linus Åkesson)把这句话重新解读为“柯尼汉杠杆(Kernighan's Lever)”,意思是:在努力修改超出自己水平的代码的过程中,实力反而会得到提升。不过,这是就学习场景而言;对于多人长期使用的代码,原来的建议更为稳妥。


在实际工作中运用柯尼汉定律的方法

明亮的办公室里,两位同事并排坐着一起看大显示器,一人指着屏幕,另一人点头

柯尼汉定律可以延伸出许多让代码更易读的习惯。

(1)先想到读代码的人
代码写一次,却要被读很多次。要把名字起得清楚明白,让几个月后的自己或第一次看到代码的同事都能立刻看懂,也不要把太多事情塞进一行。

(2)先写对,再写快
同一本书建议:“先写对,再求快(Make it right before you make it faster)。”为了性能而把代码改得拐弯抹角,等确认了真正慢的地方再做也不迟。

(3)比起短的代码,选择容易修改的代码
如今,人工智能工具能在转眼间生成复杂的代码,但理解和修改这些代码的责任依然在人身上。自己解释不了的代码,最好不要原样接受。

柯尼汉在1979年的文章中还说过,最有效的调试工具依然是审慎的思考,再加上放在恰当位置的打印语句。也就是说,比起花哨的工具,能让人冷静推敲的简单代码才是解决问题的基础。


柯尼汉定律并不是叫人隐藏实力,而是告诉我们实力该用在哪里。比起今天写下的聪明的一行,明天依然读得顺畅的平凡十行,最终能省下更多时间。

只写到自己的头脑还能再解开的聪明程度——这正是写出长久代码的第一步。