在SciPy 大会上,一位发言人给我们展示了几段简短的代码,并且问我们每段代码都是做什么用的。代码写的很明了,但没有提供上下文的注解。下面的就是这最后一段代码:
def what( x, n ): if n < 0: n = -n x = 1.0 / x z = 1.0 while n > 0: if n % 2 == 1: z *= x x *= x n /= 2 return z
这个测试是在这天快要结束时进行的,我有些累了。我说不出这段代码是干什么用的。可后来我发现自己处于很尴尬的境地,其实这段代码所实现的算法我是十分熟悉的。我曾经写过相同的代码,而且还写在了博客里。
这个事件使我改变了对“自我注解”程序的理解。没有上下文的提示,你很难理解一段代码是干什么用的,即使是很小一段。
有意义的变量名称和函数名能给理解程序带来很大帮助,但一句简单的注释带来的帮助更大。我们不需要那些冗余的注释,就像解释这行代码x = 1.0 / x
是取一个数的倒数,我们要的注释是能解释这段代码是来解决什么问题的。
这还有个例子,你认为这段代码是干什么的?
uint what() { m_z = 36969 * (m_z & 65535) + (m_z >> 16); m_w = 18000 * (m_w & 65535) + (m_w >> 16); return (m_z << 16) + (m_w & 65535); }
很明显这段代码是处理底层问题的 — 它只有一些操作 — 但我们完全不知道它是干什么的。
在继续往下读之前你最好尽力思考一下这段代码。如果你放弃了,那我告诉你,上面的第一段代码是来自这里的,第二段代码是来自这里的。
在通常我们的面对面交流中,有很多的信息是来自口头表达之外的。我们通常会认为我们的语言表达是最重要的,但是我们的语调,面部表情,肢体语言等传递了更多的信息。程序源代码跟这些很相似,我们通常会在里面隐含着大量的其它信息。
假设你的同事Sam请你帮他审查一下他的代码。工作中发生这种情况一般你能得到大量的上下文语境帮助;它们并不是网上的某个随机的代码片段。更特殊的是,你还对Sam所工作的项目有相当的了解。你知道Sam为什么希望你帮他看一下他的代码。也许他想炫耀一下他引以为豪的杰作,或者他希望你帮他找出一个bug。你在看他的代码之前已经有了相当的了解。
但如果你是个接手人。Sam不幸被车撞了,你被要求在Sam出院之前维护他写的代码。你很可能会向他的同事抱怨,说他写的代码是如此的糟糕,但他的同事却不理解你为什么要这样说。他的同事会认为Sam的代码非常的清晰易懂。
再假设你是Sam接手人,而且在世界的另一端。你不能跟他的同事很好的交流,你只知道很少的上下文语境。在痛苦的折磨后,你把你修改的程序发回Sam的公司。你把你的程序注释的非常充分,但Sam的同事却抱怨你的代码乱极了,你并没把问题真正的解决。
共事共识比源代码注释更有价值。所以说替换一个程序员的代价是巨大的,即使是他走时留下的是注释很好的程序。
我只想说 程序员 很喜欢自虐。。
如果把第一个方法命名为Power或者PowerInt,第二个方法命名为Random,注释仍然是多余的。这完全不能使我改变了对“自我注解”的看法,反而放我更认同“自我注解”,如果写代码的人也懂得“自我注解”他一定会取个好名字。
看不出第一段代码跟电源,功率,或者中断有什么关系。
人家说的是幂次……
http://en.wikipedia.org/wiki/Exponentiation#Particular_bases
赞同
很多时候注释的功能能用函数名替换。
神一样的注释也不能弥补猪一样的命名