欢迎光临

木子屋

标题: 谈谈年度最佳代码“不管你们信不信，反正我信了”

作者: dnawo

日期: 2011-08-15 02:57 PM

分类: Win编程

内容: 最近有段十分流行的代码，是从江湖传闻“身怀八蛋”的铁道部发言人王勇平同志的一句名言：“不管你们信不信，反正我信了……这是生命的奇迹……它就是发生了”所引申出来的。这段代码虽然只是在调侃，但是围绕这段代码也产生了一些讨论（如代码风格，编程规范等等），在此顺手记录一下，就当无聊罢。
这段代码是这样的：
复制内容到剪贴板 程序代码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内部的代码也会被编译器优化掉。您怎么看，为什么呢？

+ 查看当前日志评论 (0)

登录

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.859 ms

返回

标题: 谈谈年度最佳代码“不管你们信不信，反正我信了”

你没有权限发表评论

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.859 ms

返回

暂无评论

返回

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.906 ms

返回