单一决策和行动陈述的首选风格是什么?
-
08-06-2019 - |
题
对于支持不带括号的单一决策和操作的语言,例如以下示例:
if (var == true)
doSomething();
写这个的首选方式是什么?是否应该始终使用括号,还是应该将其使用保留为各个开发人员的偏好?此外,这种做法是否取决于代码块的大小,例如以下示例:
if (var == 1)
doSomething(1);
else if (var > 1 && var < 10)
doSomething(2);
else
{
validate(var);
doSomething(var);
}
解决方案
确实没有正确的答案。这就是公司内部编码标准的用途。如果你能在整个公司保持一致,那么它就会很容易阅读。我个人喜欢
if ( a == b) {
doSomething();
}
else {
doSomething();
}
但这是一场圣战。
其他提示
我建议
if(a==b)
{
doSomething();
}
因为我发现预先执行此操作比在向成功条件添加第二个语句时尝试记住添加大括号要容易得多...
if(a==b)
doSomething();
doSomethingElse();
与
if(a==b)
{
doSomething();
doSomethingElse();
}
看 乔尔的文章 欲了解更多详情
我倾向于始终使用牙套。您可能会在开始时遇到一些微妙的错误,例如:
if(something)
DoOneThing();
else
DoItDifferently();
然后决定添加另一个操作 else
子句并忘记将其用大括号括起来:
if(something)
DoOneThing();
else
DoItDifferently();
AlwaysGetsCalled();
AlwaysGetsCalled()
总是会接到电话,如果你在凌晨 3 点坐在那里想知道为什么你的代码表现得很奇怪,那么类似的事情可能会让你在相当长的一段时间内无法理解。仅出于这个原因,我总是使用牙套。
我的偏好是保持一致,例如,如果您在一个块上使用括号,请在整个块中使用括号,即使只有一个语句:
if (cond1)
{
SomeOperation();
Another();
}
elseif (cond2)
{
DoSomething();
}
else
{
DoNothing();
DoAnother();
}
但如果你只有一堆单衬:
if (cond1)
DoFirst();
elseif (cond2)
DoSecond();
else
DoElse();
这样看起来更干净(如果您不介意虚拟方法名称;),但这只是我的想法。
这也适用于循环结构等:
foreach (var s as Something)
if (s == someCondition)
yield return SomeMethod(s);
您还应该考虑到这是一个可能更适合 .NET 的约定(请注意,Java peepz 喜欢将第一个大括号与 if 放在同一行)。
将此归因于缺乏经验,但在我担任代码猴子的七年时间里,我已经 绝不 实际上看到有人在向没有大括号的块添加代码时犯了不添加大括号的错误。正是如此 零 次。
在俏皮话开始之前,不,原因不是“每个人都总是使用大括号”。
所以,一个诚实的问题——我真的很想得到实际的答复,而不仅仅是反对票:这真的发生过吗?
(编辑:我听过足够多的外包恐怖故事来澄清一下:它真的发生过吗 有能力的程序员?)
其实这并不重要,只要你能坚持下去。
似乎确实有一种趋势,要求在单个声明中保持相同,即如果一个分支中有括号,则到处都有括号。其一,Linux 内核编码标准强制要求这一点。
我会强烈提倡 总是 使用大括号,即使它们是可选的。为什么?看看这段 C++ 代码:
if (var == 1)
doSomething();
doSomethingElse();
现在,有人并没有真正给予足够的关注,并决定需要发生一些额外的事情 if (var == 1),所以他们这样做:
if (var == 1)
doSomething();
doSomethingExtra();
doSomethingElse();
这一切仍然是美丽的缩进,但它不会达到预期的效果。
通过始终使用大括号,您更有可能避免此类错误。
我个人支持 McConnell 在 Code Complete 中的解释。
尽可能使用它们。它们增强了代码的可读性并消除了可能发生的少数和稀有的混乱。
但有一件事更重要……一致性。无论您使用哪种风格,请确保始终以相同的方式进行操作。
开始写一些东西,比如:
If A == true
FunctA();
If B == "Test"
{
FunctB();
}
您最终肯定会寻找一个奇怪的错误,其中编译器无法理解您想要做什么,并且很难找到。
基本上每次都找到你觉得舒服的那一篇并坚持下去。我确实相信尽可能多地使用块分隔符('{','}')是可行的方法。
我不想在另一个问题中提出一个问题,但我想提一下与此相关的一些事情,以激发您的精神活力。已做出使用括号的决定。您将开口支架放在哪里?与声明在同一行或下方。括号是否缩进?
If A == false {
//calls and whatnot
}
//or
If B == "BlaBla"
{
//calls and whatnot
}
//or
If C == B
{
//calls and whatnot
}
请不要回答这个问题,因为这是一个新问题。如果我发现对此感兴趣,我将提出一个新问题,供您提出意见。
我一直都使用方括号,除了在释放变量之前检查变量是否为 NULL 的情况,就像 C 中所必需的那样
在这种情况下,我通过将所有内容都放在一行上来确保它是一个单独的语句,如下所示:
if (aString) free(aString);
上述陈述的写法没有正确或错误之分。有很多可接受的编码 风格. 。然而,对我来说,我更喜欢在整个项目中保持编码风格一致。IE。如果项目使用K&R风格,则应该使用K&R。
Ruby 很好地消除了讨论中的一个问题。单行的标准是:
do_something if (a == b)
对于多行:
if (a == b)
do_something
do_something_else
end
这允许简洁的一行语句,但如果从单行变为多行,它会迫使您重新组织语句。
AFAIK,这在 Java 和许多其他语言中尚不可用。
正如其他人提到的,在没有大括号的两行中执行 if 语句可能会导致混乱:
if (a == b)
DoSomething();
DoSomethingElse(); <-- outside if statement
因此,如果可以在不影响可读性的情况下将其放在一行中:
if (a == b) DoSomething();
其他时候我都会使用牙套。
三元运算符有点不同。大多数时候我在一行上完成它们:
var c = (a == b) ? DoSomething() : DoSomethingElse();
但是有时,这些语句具有嵌套函数调用或lambda表达式,这使得很难在视觉上解析一线语句,因此我更喜欢这样的东西:
var c = (a == b)
? AReallyReallyLongFunctionName()
: AnotherReallyReallyLongFunctionOrStatement();
仍然比 if/else 块更简洁,但很容易看出发生了什么。
太阳的 Java 编程语言的代码约定 有 这 说:
IF-ELSE类的语句类别应具有以下形式:
if (condition) { statements; } if (condition) { statements; } else { statements; } if (condition) { statements; } else if (condition) { statements; } else { statements; }
无论如何,我们的老板都会让我们在决策语句后面加上 { },即使它是单个语句。额外添加两行确实很烦人。唯一的例外是三元运算符。
我想我的代码监视器纵向分辨率为 1200x1600,这是一件好事。
我更喜欢
if (cond)
{
//statement
}
即使只有一个声明。如果您打算编写一次某些内容,并且毫不怀疑它可以工作,并且从未计划让其他编码人员查看该代码,那么请继续并使用您想要的任何格式。但是,额外的包围究竟要花多少钱?一年的时间比写这篇文章所花费的时间还少。
是的,我也喜欢将括号缩进到块的水平。
Python 的优点在于缩进定义了块。在这样的语言中,这个问题毫无意义。
我倾向于同意 Joel Spolsky 在那篇文章中的观点(让错误的代码看起来错误)与以下代码示例:
if (i != 0)
bar(i);
foo(i);
Foo 现在是无条件的。威奇真的很糟糕!
我总是使用括号来表示决策语句。它有助于代码的可维护性,并使代码不易出现错误。
当且仅当至少其中一个语句需要时,我才在每个语句周围使用大括号。
在 Perl 中,如果你正在做一个简单的测试,有时你会写成这样的形式:
do_something if condition;
do_something unless condition;
这对于在子例程开始时检查参数非常有用。
sub test{
my($self,@args) = @_;
return undef unless defined $self;
# rest of code goes here
}
黄金法则是,在现有项目中工作时,请遵循这些编码标准。
当我在家时,我有两种形式。
第一个是单行:
if (condition) doThis();
第二个是多行:
if (condition) {
doThis();
}
我曾经像一个官员一样遵循“始终使用大括号”的路线。但是,我修改了我的样式以允许在单行条件表达式上省略它们:
if(!ok)return;
对于任何多语句场景,尽管我仍然认为大括号应该是强制性的:
if(!ok){
do();
that();
thing();
}