谈谈年度最佳代码“不管你们信不信,反正我信了”

标签: 语言编程 实践优化 | 发表时间:2011-08-06 13:58 | 作者:[email protected] (老赵) Coolxll
出处:http://blog.zhaojie.me/

最近有段十分流行的代码,是从江湖传闻“身怀八蛋”的铁道部发言人王勇平同志的一句名言:“不管你们信不信,反正我信了……这是生命的奇迹……它就是发生了”所引申出来的。这段代码虽然只是在调侃,但是围绕这段代码也产生了一些讨论(如代码风格,编程规范等等),在此顺手记录一下,就当无聊罢。

这段代码是这样的:

try
{
    if (you.believe(it) == true || you.believe(it) == false)
    {
        I.believe(it);
    }
}
catch (Exception ex)
{
    throw new Exception("It's a miracle!");
}
finally
{
    it.justHappened();
}

代码与原文的对应关系不言自明,从命名风格上看,我们默认其为Java代码。话题主要是围绕在if条件的写法上。

书写风格

先来看看它的书写风格问题。我说这段代码不是老鸟写的,因为老鸟不会把一个布尔表达式跟true和false直接判断,而会写成:

if (you.believe(it) || !you.believe(it))

于是有朋友提出,把布尔表达式跟true或false相比较来的更清晰一些,我表示这话并没有什么道理,因为这种读代码的方式是把视角停留在“数据”层面上:一个布尔表达式返回了布尔型的“数据”,于是把它和另外一个“数据”进行比较。如今的编程都在不断强调“语义”,“语义”的清晰才是真的清晰。我说Java是一门糟糕的语言,主要原因就是指它的表达能力太差,导致写出来的代码体现不出问题的解决方式,让人们把目光都集中在具体每条语句上了,所谓“见木不见林”。C#等现代语言都在强调“做什么”而不是“怎么做”,语义上就有很大提高了。

回到目前这个具体问题上,if里面的语义是“you.believe(it)”的返回结果,而不是它的值与另外一个布尔常量的比较结果。其实这个观点我从初中搞信息学竞赛时就被老师不断强调,今天我同样咨询了同事,他也赞同我的观点。如果您还继续坚持这种写法不太清晰的话,我只能说“这只是不适应而已,要让自己适应这类写法”,很多人还觉得LINQ不清晰呢,小学生还觉得高中数学的解法不清晰呢。

还有朋友认为,作为编码规范,应该要求这么写,例如:

if (10 == i)

就是说,把常量写在比较操作的左边,并认为“这样更有普遍意义”。其实这也没有必要,这个习惯是从C语言时代遗传下来的“陋习”。在C语言里,如果把常量写在比较右侧,并且一不小心把“比较”操作符(两个等号)写成“赋值”操作符(一个等号),也可以编译通过,但是结果却大不相同,这给错误排查也会带来许多麻烦。但是,在如今的语言里已经比C语言做的安全多了,所以没必要制定这种规范。把一种语言的标准带入另一种语言不叫做“有普遍意义”,只是多余。

代码含义

然后要谈的便是代码与那句话的“映射”关系了,再来仔细读一下这个if子句:

if (you.believe(it) || !you.believe(it))
{
    I.believe(it);
}

从“需求”上来理解,我认为代码应该保证if内部的代码一定会执行。那么现在这个需求肯定会满足吗?不一定,因为you.believe方法可能是有副作用的:如果它第一次调用返回false,而第二次调用时返回true,则if内部的代码就会整段略过,这显然不是铁道部王发言人的意图。因此,有同学提议代码应该是这样的:

if (true || you.believe(it))

这么做的确可以忽略you.believe(it)的结果,因为它已经被短路了根本不会执行。可能它也能满足需求,但我想更合理的做法可能应该是:

if (you.believe(it) || true)

这段代码与之前的区别就在于you.believe(it)一定会被调用一次,但是无所谓其结果是如何,这充分符合天朝某些部门喜欢装摸作样“咨询民意”的状况。

扩展思考

最后再来一道扩展思考题吧:有人把“你爱,或者不爱我,爱就在那里,不增不减”写成了一段C#代码:

if (you.Love(me) || !you.Love(me))
{
    love++;
    love--;
}

有人说,这段代码的if条件本身应该被编译器优化掉,因此会直接执行if内部的代码。还有人说,if内部的代码也会被编译器优化掉。您怎么看,为什么呢?

相关 [代码 不信] 推荐:

谈谈年度最佳代码“不管你们信不信,反正我信了”

- Coolxll - 老赵点滴 - 追求编程之美
最近有段十分流行的代码,是从江湖传闻“身怀八蛋”的铁道部发言人王勇平同志的一句名言:“不管你们信不信,反正我信了……这是生命的奇迹……它就是发生了”所引申出来的. 这段代码虽然只是在调侃,但是围绕这段代码也产生了一些讨论(如代码风格,编程规范等等),在此顺手记录一下,就当无聊罢. 代码与原文的对应关系不言自明,从命名风格上看,我们默认其为Java代码.

谈谈年度最佳代码“不管你们信不信,反正我信了” - 追求编程之美

- Liam - blog.zhaojie.me
最近有段十分流行的代码,是从江湖传闻“身怀八蛋”的铁道部发言人王勇平同志的一句名言:“不管你们信不信,反正我信了……这是生命的奇迹……它就是发生了”所引申出来的. 这段代码虽然只是在调侃,但是围绕这段代码也产生了一些讨论(如代码风格,编程规范等等),在此顺手记录一下,就当无聊罢. 代码与原文的对应关系不言自明,从命名风格上看,我们默认其为Java代码.

代码重构

- - ITeye博客
随着程序的演化,我们有必要重新思考早先的决策,并重写部分代码. 代码需要演化;它不是静态的事物. 重写、重做和重新架构代码合起来,称为重构.    当你遇到绊脚石  ---  代码不在合适,你注意到有两样东西其实应该合并或是其他任何对你来说是"错误"的东西  -------- . 如果代码具备以下特征,你都应该考虑重构代码:.

代码小比较

- Tim - 斯巴达第二季
判断上百万个4k的buffer是否为全0,我最先想到的办法是:zero_buffer = malloc(4096);. /* 循环百万次读取buffer */.         /* 全0 */. 由于好奇,看看shell工具cp的代码,它的解决办法是:. /* 循环百万次读取buffer */.         /* 全0 */.

两行 JavaScript 代码

- MessyCS - Dreamer's Blog
最近看到了两行 JavaScript 代码,很受启发. 在 JavaScript 中,我们可以获取HTML元素的属性值,例如 element.id. 但是,因为 for 和 class 是 JavaScript 中的关键字,所以在 JavaScript 中这两个属性名称分别用 htmlFor 和 className 代替,于是在封装的时候需要先对这两个属性进行特殊判断.

Netty代码分析

- LightingMan - 淘宝JAVA中间件团队博客
Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序[官方定义],整体来看其包含了以下内容:1.提供了丰富的协议编解码支持,2.实现自有的buffer系统,减少复制所带来的消耗,3.整套channel的实现,4.基于事件的过程流转以及完整的网络事件响应与扩展,5.丰富的example.

python代码调试

- - 阿里古古
【转自: http://blog.csdn.net/luckeryin/article/details/4477233】. 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序. 例如,有模拟税收计算的程序:. debug_demo函数计算4500的入账所需的税收. 在需要插入断点的地方,加入红色部分代码:如果_DEBUG值为True,则在该处开始调试(加入_DEBUG的原因是为了方便打开/关闭调试).

ios代码开源

- - CSDN博客移动开发推荐文章
本人从10年开始搞ios开发,从菜鸟到现在的入门,期间遇到了许多困难,也总结了一些东西,本着开源精神,希望大家共同成长的目的把这个工程开源出来.. 这个工程是从11年到13年之前完成的.主要是我平时用到的一些基础功能模块.其中有其他开源的代码和我自己写的一些.代码结构基本乱,12年以后的代码结构还可以,不是很乱,之前水平有限,如果不怎么样就别喷我了.

Oracle错误代码

- - 数据库 - ITeye博客
ORA-00001: 违反唯一约束条件 (.). ORA-00017: 请求会话以设置跟踪事件. ORA-00018: 超出最大会话数. ORA-00019: 超出最大会话许可数. ORA-00020: 超出最大进程数 (). ORA-00021: 会话附属于其它某些进程;无法转换会话. ORA-00022: 无效的会话 ID;访问被拒绝.

Java代码优化

- - ImportNew
2016年3月修改,结合自己的工作和平时学习的体验重新谈一下为什么要进行代码优化. 在修改之前,我的说法是这样的:. 就像鲸鱼吃虾米一样,也许吃一个两个虾米对于鲸鱼来说作用不大,但是吃的虾米多了,鲸鱼自然饱了. 代码优化一样,也许一个两个的优化,对于提升代码的运行效率意义不大,但是只要处处都能注意代码优化,总体来说对于提升代码的运行效率就很有用了.