我一直认为括号提高了可读性,但在我的教科书中有一句话说使用括号会大大降低程序的可读性。有没有人有任何例子?
8 回答
我可以找到很多反例,其中缺少括号会降低可读性,但对于作者可能的意思,我能想到的唯一例子是这样的:
if(((a == null) || (!(a.isSomething()))) && ((b == null) || (!(b.isSomething()))))
{
// do some stuff
}
在上述情况下,方法调用周围的 () 是不必要的,并且这种代码可能会受益于将术语分解为变量。由于所有这些接近的括号都处于条件中间,因此很难确切地看到什么与什么组合在一起。
boolean aIsNotSomething = (a == null) || !a.isSomething(); // parens for readability
boolean bIsNotSomething = (b == null) || !b.isSomething(); // ditto
if(aIsNotSomething && bIsNotSomething)
{
// do some stuff
}
我认为以上内容更具可读性,但这是个人意见。这可能就是作者所说的。
括号的一些好的用途:
- 当没有括号的行为发生变化时区分操作顺序
- 当行为不受影响时区分操作顺序,但对绑定规则不够了解的人会阅读您的代码。好公民规则。
- 指示括号内的表达式在用于更大的表达式之前应进行评估:
System.out.println("The answer is " + (a + b));
可能混淆使用括号:
- 在它不可能有其他含义的地方,比如上面的前面
a.isSomething()
。在 Java 中, ifa
是一个Object
,!a
本身就是一个错误,所以显然!a.isSomething()
必须否定方法调用的返回值。 - 将大量条件或表达式链接在一起,如果分解会更清晰。就像上面的代码示例一样,将大的附加语句分解成更小的块可以让代码更直接地在调试器中逐步执行,并且如果代码后面需要条件/值,你不要结束重复表达并做两次工作。但是,这是主观的,如果您只在一个地方使用表达式并且您的调试器无论如何都会向您显示中间评估的表达式,那么这显然是没有意义的。
显然,您的教科书是由讨厌 Lisp 的人编写的。
无论如何,这是一个品味问题,每个人都没有单一的真理。
我认为括号不是提高代码可读性的最佳方法。您可以使用新行来为 if 语句中的示例条件下划线。如果不需要,我不使用括号。
好吧,考虑这样的事情:
Result = (x * y + p * q - 1) % t
和
Result = (((x * y) + (p * q)) - 1) % t
我个人更喜欢前者(但这只是我),因为后者让我认为括号是为了改变实际的操作顺序,而实际上他们并没有这样做。您的教科书也可能会提到何时可以将计算拆分为多个变量。例如,在求解二次方时,您可能会遇到这样的情况ax^2+bx+c=0
:
x1 = (-b + sqrt(b*b - 4*a*c)) / (2*a)
这看起来有点难看。在我看来,这看起来更好:
SqrtDelta = sqrt(b*b - 4*a*c);
x1 = (-b + SqrtDelta) / (2*a);
这只是一个简单的例子,当你使用涉及大量计算的算法时,事情会变得非常丑陋,因此将计算分成多个部分将比括号更有助于可读性。
当括号明显是多余的时,括号会降低可读性。读者期望他们出现是有原因的,但没有任何原因。因此,认知打嗝。
“显然”多余是什么意思?
如果可以在不改变程序含义的情况下删除括号,则括号是多余的。
用于消除中缀运算符歧义的括号不是“明显多余的”,即使它们是多余的,除非在乘法和加法运算符的非常特殊的情况下。原因:许多语言的优先级在 10 到 15 级之间,许多人使用多种语言工作,没有人可以期望记住所有规则。消除歧义通常更好,即使括号是多余的。
所有其他多余的括号显然是多余的。
多余的括号经常出现在学习新语言的人编写的代码中;也许对新语法的不确定性导致了防御性的括号。消灭他们!
你问的是例子。以下是我在初学者编写的 ML 代码和 Haskell 代码中反复看到的三个示例:
之间的括号
if (...) then
总是多余的和分散注意力的。它们使作者看起来像一个 C 程序员。就写吧if ... then
。变量周围的括号很愚蠢,如
print(x)
. 变量周围永远不需要括号;应编写功能应用程序print x
。如果函数应用程序是中缀表达式中的操作数,则函数应用程序周围的括号是多余的。例如,
(length xs) + 1
应该总是写
length xs + 1
任何极端和/或过度使用的东西都可能使代码不可读。用评论提出同样的主张并不难。如果你曾经看过几乎每一行代码都有注释的代码,你会告诉你它很难阅读。或者,您可以在每一行代码周围留有空白,这将使每一行易于阅读,但通常大多数人希望将相似的相关行(不保证使用突破方法)组合在一起。
您必须对它们进行过度使用才能真正损害可读性,但是出于个人喜好,我总是发现;
return (x + 1);
并且在 C 和 C++ 代码中类似,非常烦人。
如果一个方法不带参数,为什么需要一个空()
来调用method()
?我相信 groovy 你不需要这样做。