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

标签: 代码 不信 编程 | 发表时间:2011-08-07 15:02 | 作者:(author unknown) Liam
出处: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内部的代码也会被编译器优化掉。您怎么看,为什么呢?

相关 [代码 不信 编程] 推荐:

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

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

android 编程代码规范

- - CSDN博客推荐文章
                学习android开发已经有很长时间了,但是有时代码却很少用规范的模式进行书写,下面就简要的总结了自己学习的代码规范. 一、关于一些常量值资源的书写规范. 颜色值有RGB和透明信息Alpha组成,以#开头, 形式有 #RGB                        #ARGB                        #RRGGBB                    #AARRGGBB.

让代码更美:10大编程字体

- Psyche - cnBeta.COM
日复一日的编写代码,有没有感到审美疲劳. 也许些许的改变就能让我们感到生活更美好. 下面我眼中的十大编程字体:.

代码审查和不良编程习惯

- - 外刊IT评论网
有时候,做为一个程序员,我觉得我的职业生涯会被我开发软件使用的开发工具和技术架构明显的分割成几个阶段. 一部分是因为使用的编程语言——在大学时是 Smalltalk,在Gog Creek公司是C#和Python,而另一方面是开发工具. 我在Fog Creek公司里工作了8年,在那里,我们有一个非常固定的技术架构:bug管理、客户支持和文档管理用 FogBugz;开发管理用 Trello;代码审查用 Kiln;版本控制用 Mercurial;编码用Vim和 Visual Studio ;持续集成用我们的内部工具Mortar;随着时间的流逝,这些工具在慢慢的变化,但变化从来都是缓慢逐步的,一个组件一个组件的.

结对编程 VS 代码审查:对比开发者文化

- - ITeye资讯频道
从上一份工作到现在的这份工作,我从结对编程的开发文化过渡到同行代码审查,这个转变过程是一个非常有趣的经历. 我认为我要记录下些我所注意到的变化. 你可以找到很多标题是/(结对编程|代码审查)的(利|弊)/这种样式的文章,这些文章的作者都可以给出一套清晰且有说服力执行方案. 我认为只要权衡它们的利弊,这两种方案都是非常有效率的.

硅谷流行结对编程:一人负责写代码另一人监控

- - TechWeb 今日焦点 RSS阅读
结对编程的坚定支持者Facebook程序员肯特--贝克(腾讯科技配图).   腾讯科技讯(马乔)北京时间8月28日消息,据国外媒体报道,英国著名女作家弗吉尼亚•伍尔芙(Virginia Woolf)认为,一位女作家应该拥有一个属于她自己的房间. 而在美国硅谷,部分科技公司则对程序员是否需要属于自己的独立工作空间表示质疑.

转:编程的艺术:漂亮的代码和漂亮的软件

- - 膘叔
最近在转一些装波一文,发发牢骚而已. 现实中除了那些API和一些开源软件,真的很少看得到漂亮的代码,不过有一天帅朱给我看过一段代码,不错. 原文来自:http://kb.cnblogs.com/page/132236/. 译者:legendsland.   编程很有意思,是因为我可以做一些很酷的东西,但是实际上让我着迷的却是那一行行代码的语法和语义.

我读过的最佳编程书:一本没有代码的书

- - 博客园_新闻
英文原文: Best development book I've read, has no code in it.. Dave Hoover 和 Adewale Oshineye 合著的《 软件开发者路线图:从学徒到高手》是一本优秀的书籍,它能为技术人员提供很好的帮助. 书中主要体现的思想就是人应该沿着一条漫长的道路坚持走下去.

职业感悟:代码审计与编程在渗透中的重要性

- - Seay's blog 网络安全博客
   配图:3D立体街头涂鸦.      博客连着断了一个月没更新,期间写过好几篇各个方向的文,都是写到一半就夭折,这篇文章强迫自己耐心写出来的. 最近跟出版社沟通好了在写一本关于代码审计和安全编程的书,算是把我这几年的技术积累做一个总结,刚好昨天跟safekey team几个搞渗透的朋友说到编程的问题,就想写个文来好好讲讲.

每日站会、代码审查、结对编程 之开源中国实践

- - 翟志军
在我来到开源中国之后,尝试将每日站会、代码审查、结对编程这三种编程实践带入团队. 而这个过程,我个人觉得是一项非常宝贵的体验. 先介绍下目前我们团队的结构:3名Java开发,1名前端,2名实习. 以下我不会详细介绍它们分别是什么,也无意讨论它们有什么好处坏处,本文侧重分享在实践它们的过程可能遇到的问题,以及我们是如何处理的.