题
这不是一场圣战,这不是“哪个更好”的问题。
对单语句 if 块使用以下格式有哪些优点。
if (x) print "x is true";
if(x)
print "x is true";
相对于
if (x) { print "x is true"; }
if(x) {
print "x is true";
}
如果您将单个语句 if 的格式设置为不带方括号 或者知道有这样做的程序员,是什么导致您/他们首先采用这种风格?我特别感兴趣的是这给您带来了什么好处。
更新:由于最受欢迎的答案忽略了实际的问题(即使它提出了最明智的建议),因此这里是无括号专家的综述。
- 紧凑
- 对某些人来说更具可读性
- 括号调用作用域,在某些情况下会产生理论上的开销
解决方案
我发现这个:
if( true ) {
DoSomething();
} else {
DoSomethingElse();
}
比这个更好:
if( true )
DoSomething();
else
DoSomethingElse();
这样,如果我(或其他人)稍后返回此代码以向其中一个分支添加更多代码,我将不必担心忘记将代码括在大括号中。我们的眼睛会在视觉上看到缩进作为我们想要做什么的线索,但大多数语言不会。
其他提示
我非常不喜欢任何将 if 测试和正文放在同一行的风格。
这是因为共享行使得在许多调试器中无法在 if 主体上设置断点,因为断点通常是基于行号的。
始终使用牙套是一个好主意,但是始终给出的标准答案:“如果有人添加一条代码并忘记添加牙套怎么办?”是一个相当弱的理由。
有一个微妙的错误,可以通过从一开始就没有大括号来引入。这种情况在我身上发生过几次,而且我也见过其他程序员也发生过这种情况。
它以一个简单的 if 语句开始,非常天真。
if (condition)
do_something();
else
do_something_else();
这一切都很好。
然后有人出现并在 if 中添加另一个条件。他们无法使用 && 将其添加到 if 语句本身,因为逻辑不正确,因此他们添加了另一个 if。我们现在有:
if (condition)
if (condition2)
do_something();
else
do_something_else();
你看到问题了吗?它可能看起来是正确的,但编译器会以不同的方式看待它。它看起来像这样:
if (condition)
if (condition2)
do_something();
else
do_something_else();
这意味着完全不同的东西。编译器不关心格式。else 与最接近的 if 一起使用。另一方面,人类依赖格式化,很容易错过这个问题。
我总是用
if(x)
{
print "x is true";
}
如果在当前行之后添加了一行,则省略大括号可能会导致维护代码的人错误地认为他们正在添加到 if 子句。
我用
if (x) { DoSomething(); }
对于多行,但我更喜欢无括号单行:
if (x) DoSomething(); else DoSomethingElse();
我发现视觉上令人反感的无关括号,并且在添加另一个语句时,我从未犯过上述错误之一。
if
{
// code
}
else
{
// else code
}
因为我喜欢代码块排列起来(包括它们的大括号)。
如果我编码:
if(x)
print "x is true";
6 个月后需要添加新行,花括号的存在使得我不太可能输入
if(x)
print "x is true";
print "x is still true";
这会导致逻辑错误,而不是:
if(x) {
print "x is true";
print "x is still true";
}
因此,我发现大括号使此类逻辑错误更容易阅读和避免。
像马特(上面 3)一样,我更喜欢:
if (x)
{
...statement1
...statement2
}
和
if (x)
...statement
else
...statement
我认为很奇怪的是,有人可能会稍后出现并且没有意识到他们必须添加大括号以形成多行 if 块。如果这超出了他们的能力,我想知道还有什么!
if 块缺少大括号的单个语句:
优点:
- 更少的字符
- 看起来更干净
缺点:
- 均匀度:并非所有 if 块看起来都一样
- 向块添加语句时可能出现错误:用户可能会忘记添加大括号,并且 if 不会覆盖新语句。
如:
if(x)
print "x is true";
print "something else";
当我在函数开头测试中断条件时,我倾向于只使用单行,因为我喜欢使代码尽可能简单和整洁
public void MyFunction(object param)
{
if (param == null) return;
...
}
另外,如果我发现我确实想避免大括号并内联 if 子句代码,我可以将它们单行,这样对于任何在 if 确实需要添加括号的情况下添加新行的人来说都是显而易见的
我用
if (cond) {
...
} else {
...
}
- 一切都应该始终带有大括号。即使现在我在 if 块中只有一行,我稍后也会添加更多。
- 我不会将大括号放在自己的线上,因为这是毫无意义的空间浪费。
- 为了便于阅读,我很少将块与条件放在同一行。
乔尔·斯波尔斯基 写了一篇好文章: 让错误的代码看起来错误
他专门针对这个问题...
if (i != 0) foo(i);
在这种情况下,代码 100% 正确;它符合大多数编码惯例,没有什么错,但是事实是,如果您的牙套没有封闭的单个陈述物体可能会在烦您可能在那里插入另一行代码
if (i != 0) bar(i); foo(i);
…而忘记添加牙套,因此意外地使Foo(i)无条件!因此,当您看到不在牙套中的代码块时,您可能会感觉到一个微小的,不清洁的汤量,这会使您感到不安。
他建议你……
…故意构建您的代码,使您的鼻子无法清洁使您的代码更可能是正确的。
我不喜欢在不需要时使用大括号。我觉得它会增加方法中的行数并使其不可读。所以我几乎总是这样做:
if (x)
print "x is true"
for (int i=0; i<10; i++)
print "y is true"
等等。如果有人需要添加另一个语句,那么他只需添加大括号即可。即使您没有 R# 或类似的东西,这也是一个很小的问题。
尽管如此,在某些情况下,即使语句中只有一行,或者如果该行特别长,或者我需要在“if”内添加注释,我也会使用大括号。基本上,我只是使用我认为更好看的东西。
空白是你的朋友......
但话又说回来,我喜欢:
if (foo)
{
Console.WriteLine("Foobar");
}
说真的,你最后一次在任何地方的任何代码中出现错误是什么时候?
if (a)
foo();
bar();
是的,从来没有……*这里唯一真正的“专业”就是匹配周围代码的风格,并将审美之战留给刚从大学毕业的孩子们。
*(注意当 foo(); 时酒吧();是一个宏扩展,但这是宏的问题,而不是大括号和 if 的问题。)
if (x) {
print "x is true";
}
else {
do something else;
}
我总是输入大括号。这只是一个好习惯。与思考相比,打字并不是“工作”。
注意条件句之前的空格。这有助于它看起来不像方法调用。
另一种方法是写:
(a==b) ? printf("yup true") : printf("nop false");
如果您想存储一个比较简单条件的值,这将很实用,如下所示:
int x = (a==b) ? printf("yup true") : printf("nop false");
if (x)
{
print "x is true";
}
在同一列中打开和关闭大括号可以轻松找到不匹配的大括号,并在视觉上隔离块。在与“if”相同的列中打开大括号可以很容易地看出该块是条件语句的一部分。由仅包含大括号的行创建的块周围的额外空白使得在浏览代码时可以轻松地找出逻辑结构。始终显式使用大括号有助于避免人们稍后编辑代码并误读哪些语句是条件的一部分而哪些不是的问题 - 缩进可能与现实不符,但用大括号括起来总是会出现问题。
唯一一次似乎接受无支撑的情况是在方法开始时检查变量的参数时:
public int IndexOf(string haystack, string needle)
{
// check parameters.
if (haystack == null)
throw new ArgumentNullException("haystack");
if (string.IsNullOrEmpty(needle))
return -1;
// rest of method here ...
唯一的好处是紧凑。当很明显以下情况时,程序员不必费力地处理不必要的 {}:
- 该方法在任何 true 分支上退出
- 很明显这些都是 1-liners
也就是说,出于其他人所述的原因,我始终会选择程序逻辑。当您放弃大括号时,很容易在精神上保持大括号不存在并引入微妙的代码缺陷。
H8ers 见鬼去吧,我并不是一个真正喜欢教条规则的人。在某些情况下,如果它不超过一定的宽度,我实际上会倾向于紧凑性,例如:
if(x > y) { xIsGreaterThanY(); }
else if(y > x) { yIsGreaterThanX; }
else { xEqualsY(); }
这对我来说比以下更具可读性:
if( x > y ){
xIsGreaterThanY();
}else if( x < y){
yIsGreaterThanX();
}else{
xEqualsY();
}
这样做的另一个好处是鼓励人们将逻辑抽象为方法(就像我所做的那样),而不是不断地将更多逻辑集中到嵌套的 if-else 块中。它还占用三行而不是七行,这可能使得不必滚动即可查看多个方法或其他代码。
我更喜欢括号的风格,主要是因为它让眼睛有一个清晰的起点和终点。它可以更轻松地查看语句中实际包含的内容,并且它实际上是一个 if 语句。也许是一件小事,但这就是我使用它的原因。
只要它在你工作的团队中是一致的,那么这并不重要
每个人都做同样的事情才是最重要的
将单行 if 语句括起来具有相当大的理智优势,可以保护您在稍后某个时刻(或维护或更改代码的其他编码人员)需要向该条件块的某些部分添加语句时避免头痛。
如果你这样做:
if(x)
{
somecode;
}
else
{
morecode;
}
对于持有长时间的代码的源控制和预处理指令,这更好。添加#if左右的情况更容易,而无需无意间打破语句或必须添加额外的行。
习惯了有点奇怪,但是一段时间后奏效了。
如果它是一行 if (以及可选的一行 else),我宁愿不使用括号。它更具可读性和简洁性。我说我更喜欢它,因为这纯粹是一个偏好问题。尽管我认为试图强制执行必须始终使用大括号的标准有点愚蠢。
如果您不得不担心有人在 if 语句的主体中添加另一行而不添加(只有那时需要的)大括号,我认为您遇到的问题比亚拜占庭编码标准更大。
/* I type one liners with brackets like this */
if(0){return(0);}
/* If else blocks like this */
if(0){
return(0);
}else{
return(-1);
}
我从不在制表符之外使用多余的空格,但总是包含括号可以节省大量时间。
我不喜欢将大括号与 follow 关键字放在同一行:
if (x) { print "x is true"; } else { do something else; }
这使得仅删除/注释掉 else 子句变得更加困难。例如,通过将 follow 关键字放在下一行,我可以利用编辑器来选择一系列行,并立即注释/取消注释它们。
if (x) { print "x is true"; } //else { // do something else; //}
我总是更喜欢这个:
if (x) doSomething();
if (x) {
doSomthing();
doOtherthing();
}
但始终取决于您所使用的语言和操作。有时我喜欢戴牙套,有时不喜欢。取决于代码,但我编码就像必须写一次,重写十次,读一百次;所以,就按照你想要的方式去做,就像你想更快地阅读和理解一样
无论如何,这就是我要走的路!它看起来是最好的。
If(x)
{
print "Hello World !!"
}
Else
{
print "Good bye!!"
}
如果您好奇各种代码格式样式的名称是什么,维基百科上有一篇文章 缩进样式.