你有没有发现自己用Java,C#或C++编写简洁代码?
如果是这样,为什么?考虑到使用这些语言的情况,您是否认为有任何情况可以接受?
这取决于你对'简洁'的定义.
如果你的意思是"简短而重要",那么它与我对良好代码的看法非常吻合.
如果你的意思是"神秘",那就有问题了.
代码应该尽可能简洁,不再需要.:)
抛开轻率的评论,有几个因素会影响它应该是多么简洁(或其他):
寿命.
通常比你想象的要长:)
错误的可能性.
有多大可能依赖于很多东西,但原始编码器在这方面有很大的作用.
计算机读取(解析)它.
不仅仅是编译器,还有intellisense等等.
人类阅读它
有时是原始的,有时借助diff工具等程序.
有时不是那个写它的人.
所需的性能特征.
所有这些事情结合在一起产生了一系列有时相互竞争的力量,这些力量可能要求或多或少的冗长.
平衡这些是有效发展的关键.哪个更重要完全取决于您的软件试图解决的问题.
首先让我们采取简单的方法:
当他们阅读你的代码时,无论冗长程度如何,他们都能够这样做.它们可能会慢一点,但这通常很难衡量(你不太可能超过最低理论可能性的1或2个数量级).值得注意的例外是你(ab)通过预处理器使用元编程之类的东西来为你做大量的扩展.编译时可能需要很长时间.在这里你必须决定这种权衡是否值得.
一般来说,他们将是与你有相似背景的人,他们将在类似的情况下阅读来源,当你写它.这意味着如果函数在一个名为Foo的文件/类/模块中,那么就没有必要将Foo放在事物的前面,它的Foo方面应该从上下文中非常清楚.这使得将来更容易改变这一方面.
熟悉您正在使用的语言/编程风格的习惯用户的程序员将能够理解几个非常简洁的结构.例如,称为"i"的循环索引变量尽可能简洁,但在循环变大之前通常不会出现问题.
在这里,您会看到一个有趣的二分法.简洁的价值通常与其所在的代码块的复杂性成比例.随着这个块变得更加简洁,其中的变量从收缩中受益更多.通过在具有有限责任的函数/类中编写代码,使事情变得简洁和更有帮助,因为人类的混淆空间较小.矛盾的是,这可能导致需要更明确的上下文,从而更长的方法和类名.
生命周期和错误概率会影响您阅读代码或通过它调试的频率.许多调试器支持在一行上的多个点处的断点(正确地发现有两个语句的位置),但有些则没有.因此,如果您打算在其中打破很多点,以确保您可以轻松地放置和控制这些,则应该小心谨慎.
如果代码的错误概率很低但寿命很长,那么你会遇到另一个有趣的情况.当你需要改变代码时,代码可理解的概率要低得多(你的内存会更差,甚至可能不再存在).因此,此代码将比正常情况稍微简洁一些.
有时候你可能不得不牺牲一个紧凑而清晰的东西来表示满足性能目标的东西,也许你必须有点包装,例如,在代码中读取从来不是一件好事,但如果你必须适应一定量的内存则不可避免.这样的场合很少见.
一些语言结构可以鼓励简洁的代码(自动属性,匿名内部类,lambdas仅举几例).如果这些概念有意义使用,请明智地使用它们.他们的想法是减少锅炉板并暴露意图.
如果你反复做同样的事情并且有一定数量的代码重复,请考虑共享函数/类/模块,但要记住,如果必须使共享代码不那么清楚(比如在其中一个代码路径中添加一个if语句或未使用的变量)那么你可能没有净胜利.
类型推断是强大的,但请记住,编译器有时比人类更好.如果你说flibble x = new flibble()
那么var x = new flibble()
根本就没有伸展(随着flibble变得越来越好).比较var flibble = SomeMethodWhoseReturnTypeIsNotClear()
.常识在这里有所帮助,如果你永远不必使用intellisense来解决它,你当然应该考虑使用它.
一些其他有用(和简洁)的经验法则:
单行上的多个动作经常使人混淆.
副作用经常使人混淆(++ x或x ++在概念上根本不重要,除非是例如更广泛表达的一部分)
缩进有助于大多数人推断结构远远超过括号
优先规则通常由人类"内化",而不是作为一组规则记住.这意味着,对于可读性而言,不必要的(对于编译器)包围可能是有害的,其中成语是常见的但在使用不常见的情况下是有用的.
逻辑通常不是单个字符.在if语句中使用它时,请考虑是否可以将其重组为不需要它.这可能是不可能的(如果对变量/方法名称产生的扭曲或代码的排序超过了删除,请将其保留)
这取决于你的"简洁"是什么意思.我当然希望编写简洁的代码,以最简单的方式表达我想要实现的目标.例如,我喜欢LINQ让我表达数据管道的方式,而不是编写循环来转换或过滤集合的"旧"方式,或者找到最大值等等.这只是重复的代码,应该在某个模板方法中.
另一方面,较短的代码并不总是比较长的代码更易读.有条件的算子在这方面是争议的主题.方法是:
Foo x = null; if (condition) { x = y; } else { x = z; }
或多或少可读:
Foo x = condition ? y : z;
好吧,如果"条件","y"和"z"都相当简单,则条件运算符获胜.如果你必须通过箍来制作"y"和"z"单个表达式,其中执行多个语句将更具可读性,那么if/else形式可能更具可读性.
简而言之,我编写了最易读的代码.这通常(但不总是)简洁的代码.