这不是一场神圣的战争,这不是"哪个更好"的问题。
if语句对单个语句使用以下格式的优点是什么?
1 2 3 4
| if (x) print"x is true";
if(x)
print"x is true"; |
相对于
1 2 3 4
| if (x) { print"x is true"; }
if(x) {
print"x is true";
} |
如果您格式化没有括号的单个语句,或者知道有这样的程序员,那么是什么导致您(他们)首先采用了这种风格? 我特别想知道这给您带来了什么好处。
更新:由于最受欢迎的答案忽略了实际问题(即使它提出了最明智的建议),因此这里是无括号专家的综述。
紧凑
对某些人更具可读性
括号调用作用域,在某些情况下具有理论上的开销
我发现:
1 2 3 4 5
| if( true ) {
DoSomething();
} else {
DoSomethingElse();
} |
比这更好:
1 2 3 4
| if( true )
DoSomething();
else
DoSomethingElse(); |
这样,如果我(或其他人)稍后返回此代码以将更多代码添加到分支之一,则不必担心忘记将代码括在花括号中。我们的眼睛会在视觉上看到缩进作为我们正在尝试做的线索,但是大多数语言不会。
我强烈不喜欢将if的测试和正文放在同一行的任何样式。
这是因为共享行使得在许多调试器中无法在if主体上设置断点,因为断点通常基于行号。
始终使用花括号是个好主意,但始终给出标准答案:"如果有人添加一行代码而忘记添加花括号怎么办?"是一个相当薄弱的原因。
从一开始就没有括号可以引入一个细微的错误。这发生在我身上几次,我也看到过其他程序员在发生。
它从一个简单的if语句开始就足够无辜了。
1 2 3 4
| if (condition)
do_something();
else
do_something_else(); |
一切都很好。
然后有人来给if添加另一个条件。他们无法使用&&将其添加到if语句本身,因为逻辑不正确,因此他们添加了另一个if。我们现在有:
1 2 3 4 5
| if (condition)
if (condition2)
do_something();
else
do_something_else(); |
看到问题了吗?它可能看起来正确,但是编译器对它的看法有所不同。它看起来像这样:
1 2 3 4 5
| if (condition)
if (condition2)
do_something();
else
do_something_else(); |
这意味着完全不同的东西。编译器不关心格式。否则以最近的if开头。另一方面,人类依赖于格式设置,因此很容易错过该问题。
我总是用
1 2 3 4
| if(x)
{
print"x is true";
} |
省略花括号可能会导致某些人错误地维护代码,以为如果他们在当前行之后添加一行,则会认为他们正在将其添加到if子句中。
我用
1 2 3 4
| if (x)
{
DoSomething();
} |
多行,但我更喜欢无括号的衬板:
1 2 3 4
| if (x)
DoSomething();
else
DoSomethingElse(); |
我发现多余的括号在视觉上令人反感,但我从未做过
上述错误之一是在添加另一条语句时未添加方括号。
1 2 3 4 5 6 7 8
| if
{
// code
}
else
{
// else code
} |
因为我喜欢代码块排列起来(包括它们的花括号)。
如果我编码:
1 2
| if(x)
print"x is true"; |
并且6个月后需要添加新行时,花括号的出现使我键入的可能性大大降低
1 2 3
| if(x)
print"x is true";
print"x is still true"; |
与以下情况相比,这将导致逻辑??错误:
1 2 3 4
| if(x) {
print"x is true";
print"x is still true";
} |
我发现,花括号使这种逻辑错误更易于阅读和避免。
像Matt(上面的3)一样,我更喜欢:
1 2 3 4 5
| if (x)
{
...statement1
...statement2
} |
和
1 2 3 4
| if (x)
...statement
else
...statement |
我认为有些人以后可能会出现而又没有意识到他们必须添加括号以形成多行if块,这很奇怪。如果这超出了他们的能力,我想知道还有其他事情!
如果语句缺少括号,则使用单个语句:
优点:
缺点:
-
均匀性:并非所有块都一样
-
将语句添加到块中时潜在的错误:用户可能会忘记添加花括号,而if不会覆盖新语句。
As in:
1 2 3
| if(x)
print"x is true";
print"something else"; |
在函数开始时测试中断条件时,我倾向于只使用单行,因为我喜欢使这段代码尽可能简单且整洁
1 2 3 4 5 6
| public void MyFunction(object param)
{
if (param == null) return;
...
} |
另外,如果我确实想避免使用花括号并内联if子句代码,则可以将它们单行显示,这样对于在if中确实需要添加方括号的人来说很明显
乔尔·斯波斯基(Joel Spolsky)写了一篇好文章:使错误的代码看起来错误
他专门解决了这个问题
In this case the code is 100% correct;
it conforms to most coding conventions
and there’s nothing wrong with it, but
the fact that the single-statement
body of the ifstatement is not
enclosed in braces may be bugging you,
because you might be thinking in the
back of your head, gosh, somebody
might insert another line of code
there
1 2 3
| if (i != 0)
bar(i);
foo(i); |
… and forget to add the braces, and
thus accidentally make
foo(i)unconditional! So when you see
blocks of code that aren’t in braces,
you might sense just a tiny, wee,
soup?on of uncleanliness which makes
you uneasy.
他建议你
… deliberately architect your code
in such a way that your nose for
uncleanliness makes your code more
likely to be correct.
当不需要它们时,我不喜欢使用花括号。我觉得它会使方法中的行数膨胀并使它变得不可读。所以我几乎总是去做以下事情:
1 2 3 4
| if (x)
print"x is true"
for (int i=0; i<10; i++)
print"y is true" |
依此类推。如果有人需要添加另一条语句,则只需添加花括号即可。即使您没有R#或类似的东西,它也很小。
尽管如此,即使在语句中只有一行的情况下,也有一些情况下我仍会使用花括号,也就是说,如果该行特别长,或者我需要在" if"中添加注释。基本上,我只是使用看起来更好的东西来查看。
我用
1 2 3 4 5
| if (cond) {
...
} else {
...
} |
-
一切都应始终带有大括号。即使现在if块中只有一行,我以后也会添加更多。
-
我不将大括号放在自己的行上,因为这毫无意义地浪费了空间。
-
我很少将代码块与可读性放在同一行。
空格是您的朋友。
但是,我再次喜欢:
1 2 3 4
| if (foo)
{
Console.WriteLine("Foobar");
} |
其他方式是写:
1
| (a==b) ? printf("yup true") : printf("nop false"); |
如果要存储比较简单条件的值,这将是实用的,例如:
1
| int x = (a==b) ? printf("yup true") : printf("nop false"); |
1 2 3 4 5 6
| if (x) {
print"x is true";
}
else {
do something else;
} |
我总是大括号。这只是一个好习惯。与思考相比,打字不是"工作"。
注意条件之前的空格。这有助于使其看起来不像方法调用。
严重的是,这是您最后一次在任何代码中的任何地方都存在导致某人犯错的错误:
是的,从不... *这里唯一真正的"专业"是匹配周围代码的样式,并将美学之战留给刚大学毕业的孩子们。
*(caveat是当foo(); bar();是宏扩展时,但是使用宏而不是使用ifs的大括号是一个问题)
似乎唯一可以接受的是在方法开始时检查变量的参数:
1 2 3 4 5 6 7 8 9
| 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 ... |
唯一的好处就是紧凑。很明显,程序员不必遍历不必要的{}:
就是说,出于他人的原因,我将始终{}寻求程序逻辑。当放下大括号时,很容易在不存在大括号的情况下进行大括号,并引入细微的代码缺陷。
H8ers该死的,我不是一个教条主义的人。在某些情况下,如果紧凑性没有超过一定的宽度,我实际上会更喜欢紧凑性,例如:
1 2 3
| if(x > y) { xIsGreaterThanY(); }
else if(y > x) { yIsGreaterThanX; }
else { xEqualsY(); } |
对我而言,这比以下内容更具可读性:
1 2 3 4 5 6 7
| if( x > y ){
xIsGreaterThanY();
}else if( x < y){
yIsGreaterThanX();
}else{
xEqualsY();
} |
这样做还有一个好处,就是鼓励人们将逻辑抽象为方法(如我所做的那样),而不是将更多的逻辑混入嵌套的if-else块中。它也占用了三行而不是七行,这可能使得不必滚动即可查看多个方法或其他代码。
1 2 3 4
| if (x)
{
print"x is true";
} |
在同一列中打开和关闭括号,可以轻松找到不匹配的括号,并在视觉上隔离该块。在与" if"相同的列中打开花括号,可以很容易地看到该块是有条件的一部分。由仅包含大括号的行所创建的块周围的多余空白使得在略读代码时可以很容易地将其从逻辑结构中挑选出来。始终明确使用大括号可避免在以后编辑代码并误读哪些语句是条件语句的一部分和哪些不是条件时出现问题的原因-缩进可能与实际情况不符,但总是将其括在大括号中
我更喜欢方括号样式,主要是因为它可以使眼睛清楚地知道起点和终点。它使查看语句中实际包含的内容变得更加容易,并且它实际上是一个if语句。也许是一件小事,但这就是我使用它的原因。
只要您所在团队中的团队保持一致,那就没关系
每个人都做同样的事情是主要的
如果您(或以后维护或更改代码的其他编码人员)需要在该条件块的某些部分添加语句,则将单行if语句括起来具有使您免于头痛的相当理智的优势。
我一直喜欢这样:
1 2 3 4 5 6
| if (x) doSomething();
if (x) {
doSomthing();
doOtherthing();
} |
但始终取决于您所使用的语言和操作。有时我喜欢戴括号,有时不喜欢。取决于代码,但是我编码就像必须写一次,重写十遍,读一百遍;因此,只需按照自己的意愿去做,就可以更快地阅读和理解。
如果您想知道各种代码格式样式的名称是什么,Wikipedia上有一篇有关缩进样式的文章。
如果是if的一行(可能是其他的一行),我宁愿不使用方括号。它更具可读性和简洁性。我说我更喜欢它,因为这纯粹是一个优先事项。虽然我认为尝试强制执行必须始终使用花括号的标准有点愚蠢。
如果您不得不担心有人在if语句的主体中添加另一行而不是不添加(仅在那时才需要)大括号,那么我认为您的问题比拜占庭式编码标准大。
如果您执行以下操作:
1 2 3 4 5 6 7 8
| if(x)
{
somecode;
}
else
{
morecode;
} |
这对于源代码控制和预处理器指令更好
存在很长时间的代码上。添加#if左右而不添加它会更容易
无意间破坏了语句或不得不添加额外的行。
习惯有点奇怪,但经过一段时间后效果很好
而。
我不喜欢使用follow关键字在同一行上使用大括号:
1 2 3 4 5
| if (x) {
print"x is true";
} else {
do something else;
} |
这使得仅删除else子句变得更加困难。通过将follow关键字放在下一行,例如,我可以利用允许我选择一系列行并立即对其进行注释/取消注释的编辑器。
1 2 3 4 5 6
| if (x) {
print"x is true";
}
//else {
// do something else;
//} |
1 2 3 4 5 6 7 8
| /* I type one liners with brackets like this */
if(0){return(0);}
/* If else blocks like this */
if(0){
return(0);
}else{
return(-1);
} |
我从来没有在制表符之外使用多余的空格,但总是将方括号包括在内可以节省大量时间。
不管怎样,这就是我要走的路!看起来最好。
1 2 3 4 5 6 7 8
| If(x)
{
print"Hello World !!"
}
Else
{
print"Good bye!!"
} |
这种类型的任何格式都可以。人们会对此深有争议,因为这很容易理解。人们喜欢谈论自己理解的事物,而不是处理诸如设计良好和使用新算法解决难题之类的更大问题。对于单一的简单衬纸,我倾向于不使用括号。但是,我也很高兴将其与方括号一起阅读。如果给定项目有特定的样式指南,则我希望遵循该指南。我相信某些主观正确性的一致性。
我个人选择不使用单引号括起来,是因为键入的字符更少,代码更短且简洁。
到目前为止,我感觉已经投票了,但我将担保以下其中一项:
1 2 3 4 5 6
| if (expr) {
funcA();
}
else {
funcB();
} |
或者,为便于阅读,在有限情况下的速记:
1 2
| if (expr) funcA();
else funcB(); |
对我来说,速记格式很不错,希望您像英语语法一样阅读。如果代码看起来可读性不足,我将分头讲解:
1 2 3 4
| if (expr)
funcA();
else
funcB(); |
仔细考虑后,我不会在if / else块中放置嵌套条件,以避免编码器/编译器产生歧义。如果比这更复杂,我可以在if和else块上都使用大括号。
一个衬里就是...一个衬里,应该像这样保持:
1
| if (param == null || parameterDoesNotValidateForMethod) throw new InvalidArgumentExeption("Parameter null or invalid"); |
我喜欢这种风格的参数检查,例如,它紧凑且通常易于阅读。我过去经常把大括号和缩进代码放在一起,但发现在许多琐碎的情况下,它只是浪费显示器上的空格。在某些情况下放下牙套可以让我更快地掌握方法的内容,并使整体呈现过程更轻松。但是,如果更多地参与其中,那么我会像对待其他所有事情一样对待它,并且会像下面这样全力以赴:
1 2 3 4 5 6 7 8 9 10 11 12
| if (something)
{
for(blablabla)
{
}
}else if
{
//one liner or bunch of other code all get the braces
}else
{
//... well you get the point
} |
话虽这么说...我鄙视括号在同一行上,如下所示:
1
| if(someCondition) { doSimpleStuff; } |
最坏的
1 2 3
| if(somethingElse){
//then do something
} |
它更紧凑,但我发现很难跟踪括号。
总的来说,这只是一个个人品味的问题,只要它不采用某种非常奇怪的方式来缩进和支撑...
1 2 3 4
| if(someStuff)
{
//do something
} |
对我来说,花括号使查看程序流程更加容易。这也使将语句添加到if语句的主体变得更加容易。如果没有大括号,则必须添加大括号以添加另一个语句。
我猜不使用花括号的优点是它看起来更干净,并且您不会在花括号时浪费时间。
行间距和缩进可以提高可读性。
就可读性而言,我更喜欢以下内容:
1 2 3 4 5 6 7 8 9 10 11
| // Do this if you only have one line of code
// executing within the if statement
if (x)
print"x is true";
// Do this when you have multiple lines of code
// getting executed within the if statement
if (x)
{
print"x is true";
} |
我更喜欢没有括号的单行语句,我知道有这样的危险,当我插入一行新代码时,我可能会忘记添加它们,但是我不记得上一次发生这种情况了。我的编辑器(vim)阻止我编写如下内容:
1 2 3 4
| if (x)
x = x + 1;
printf("%d
", x); |
因为它会以不同的方式缩进。我唯一遇到的问题是糟糕的书面宏:
1 2 3 4 5 6
| #define FREE(ptr) {free(ptr); ptr = NULL;}
if (x)
FREE(x);
else
... |
当然这是行不通的,但是我认为最好修复宏,以避免出现那些可能的错误或问题,而不是更改格式样式。
因此,这种格式化方式可能会出现问题,但是它们并不是致命的。最终成为一个品味问题。
在提供的选项中,我会选择
1 2 3
| if (x) {
print"x is true";
} |
仅仅因为大括号是习惯打字。
但实际上,作为一个主要是Perl的程序员,我更有可能使用
(当我使用不支持后缀条件的语言时,这总是使我感到震惊。)
我还没有看到有人提到将括号与emacs中的if-括号匹配放在同一行的最有用的理由。将光标放在结束括号上时,emacs将显示带有匹配开始括号的行。将起始括号放在自己的行上会否定该功能。
我相信这是最重要的原因,
我很惊讶地发现还没有给出答案
(尽管已在评论中提及,
答案中的脚注,答案中的脚注)。
您应该始终使用方括号,因为
如果DoSomething随后被重新定义为多语句宏,则中断:
1
| #define DoSomething() statement<sub>1</sub> ; statement<sub>2</sub> ; |
当然,我们都知道正确的做法
是这样定义宏:
1
| #define DoSomething() do { statement<sub>1</sub> ; statement<sub>2</sub> ; } while (0) |
,它使宏的行为更像一条语句。
也就是说,我承认我没有听从自己的建议;
当我(似乎是)一个陈述时,我通常不使用花括号。
(垂头丧气。)
我喜欢以下内容...我认为它看起来更干净。
1 2 3 4 5 6 7 8
| if(x)
{
code;
}
else
{
other code;
} |
我希望IDE可以强制执行此行为。正如您正确指出的那样,没有"正确"的行为。一致性更重要...这可能是两种风格。
我想我比我想象的更离群。我还没有注意到这一点。
我是的粉丝
它感觉紧凑且可读(我讨厌花括号),但是它使条件的范围变得明确。
与单行if相比,它对断点更友好。在我的大括号换行符世界中,它也让您感到宾至如归:
1 2 3 4 5 6 7
| if (x)
{ foo(); }
else
{
bar();
baz();
} |
编辑:看来我误解了原来的问题,所以这个答案离题。我仍然对任何回应感到好奇。