如何写简单的代码?
来源:技术让梦想更伟大
作者:李肖遥
不知道大家有没有这样的经历,当你来到一个新的公司或者是接手一个新的项目的时候,最怕的就是看前任的代码(外加没有文档),最气人的还是,连简单的注释都没有多少,每当遇到这种情况都想把前任程序员拉出来毙了。
吐槽归吐槽,谁的新欢不是谁的旧爱呢?自己写完的项目可能也要交给后来人,那我们可能是想被毙掉的那一位了。我仔细想了想,可能一切的锅都得归于我们写代码时候的炫技
。
程序语言都会提供这样的或者那样的特性,这些特性在某些时候可以帮助我们省些代码或者在特定情况帮助我们减少失误带来的影响。我相信存在即合理,然而语言的有些特性并不是什么好东西,很多特性都经不起时间的考验(代码的不断迭代),最后带来的bug可能很难找到。
还有一点,我相信每个程序员都想要写好代码,或者认为短小精悍的代码才算好。我们也会经常吹牛逼说:这个功能别人要写100行,我不到一半行就搞定了。不是说不好,但是很多情况,利用语言里的一些特殊构造来缩减代码可能会让人难以理解。
也就是说:并不是语言提供什么特性,我们就一定要使用起来。实际上我们只需要其中很小的一部分功能,就能写出优秀的代码,实现特定的功能。
下面我根据一些经验,针对一些有问题
的语言特性,规范一些代码,为什么这样能让代码更简单。
切记不要省略花括号
这个相信大家都有体会,也是经常会这么用的,比如:
if (condition1)
action1();
而不是
if (condition1){ action1(); }
这种情况最起码可以省了一两行代码了,而且也还算是很好看。但是这样也会经常引起一些意想不到的问题,比如,在后面想要多加一句话action2()到这个if里面,有可能会把代码改成:
if (condition1)
action1();
action2();
这可不是python,当我们都有缩进的时候,潜意识里肯定是以为它们是在一起的,以为它们只会在if的条件为真的时候执行,然而action2()却其实在if外面,它会被无条件的执行。
看似很简单的问题,可能都很容易发现这个错误,但实际上却容易被忽视。只要是if-else语句,把花括号全都打上,就可以不用担心漏掉了,相当于没这个特性,这样就可以保持完全的一致性,减少不必要的思考。
if (condition1){ action1(); action2(); }
避免使用自增减表达式(i++,++i,i–,–i)
我们总喜欢骚操作,在我之前写过的一篇文章中 浅析C语言中一些“令人吃惊”的结构 ,表明C语言会同意一些'令人震惊'的结构,但实际上自增减操作表达式其实是历史遗留的设计失误。
像是c = a+++++b;
这种类型的表达式含义比较蹊跷,非常容易弄错,混淆缠绕在一起,把语义搞得乌七八糟。
这种表达式的结果可能取决于求值顺序,在某种编译器下能正确运行,换一个编译器就可能出现离奇的错误了,当然这个我并没有验证,但这种看起来太骚了。
如果你想写function(i++)
,你完全可以把它拆成
int t = i;
i += 1;
function(t);
这两个表达式分解成两步,如果想写function(++i)
,可以拆成
i += 1; function(i);
拆开之后的代码,含义完全一致,却清晰很多。到底更新是在取值之前还是之后,一目了然。
当然我们也会有更细致的争论,例如:i++或者++i的效率比拆开之后要高
,当看到这种究根源的结论我其实是很感兴趣的,但实际上这些代码经过基本的编译器优化之后,生成的机器代码是完全没有区别的。
而且自增减表达式只有在for循环的update部分
、写成单独的一行
这两种情况下才可以安全的使用,这两种情况是完全没有歧义的。其余情况需要避免使用,比如用在复杂的表达式里面,比如function(i++),function(++i)
等等。
合理使用括号
使用括号可以确保表达式的优先级,而我们总是不大喜欢在表达式中添加括号,但是盲目依赖操作符优先级往往得不偿失。
当然对于简单的加减乘除我们可以使用,比如1+4*9
,而不需要写成1+(4*9)
,然而在一些稍微复杂一点的表达式中我们可能不喜欢括号,比如1<<2+4*9
。
当然,这也考研我们的基本功,但我相信移位操作<<的优先级,大部分人第一眼可能是不大熟悉的,所以这导致了我们再一次废了多一点脑子或者Google了一下。
由于x << 1
相当于把x乘以2,那么这个表达式可能会被误以为(1<<2)+(4*9)
,然而实际上<<的优先级比加法+还要低,所以这表达式其实相当于1<<(2+4*9)
解决这个问题的办法,不是要求每个人都去把操作符优先级表给硬背下来,而是合理的加入括号。虽然没有括号也表示同样的意思,但是加上括号就更加清晰了,是不是呢?
总结
再次声明,这里只是举了几个简单的例子,所谓存在即合理,特性既然存在肯定是在某种特定情况下有用武之地的,这一点我们毋庸置疑。
但实际到我们自己敲的代码,或者在工程应用中,为了避免花过多的时间与精力放在这种费眼睛、费脑子的事情上,是适得其反的。
end