你更喜欢“if(var)”还是“if(var!= 0)”?

时间:2009-01-01 10:42:16

标签: c perl coding-style

我已经用C语言编程了几十年了。在某个地方,我决定不再写作了:

if (var)    // in C
if ($var)   # in Perl

当我的意思是:

if (var != 0)
if (defined $var and $var ne '')

我认为部分原因是我有一个强类型的大脑,在我看来,“if”需要一个布尔表达式。

或者也许是因为我使用Perl这么多,Perl中的真相和虚假就是这样一个雷区。

或者也许只是因为这些天,我主要是一名Java程序员。

您的偏好是什么?为什么?

26 个答案:

答案 0 :(得分:72)

当我大声朗读时,我喜欢我的if

if (is_it_happening) ...
if (number_of_sheep != 0) ...
if (pointer_to_something != NULL) ...

答案 1 :(得分:24)

我更喜欢

if (var != 0)

更容易阅读/理解。由于您只编写了一次代码但是阅读了很多次,因此轻松阅读比简单编写更重要。

答案 2 :(得分:22)

这很简单。 if( var )测试真实性。 if( var != 0 )测试它不是数字0. 它们不是可交换的!有三个原因。

首先,使用if( var != 0 )来测试真相会更复杂。还有更多东西可供阅读和理解。你必须要知道!=0是“真实”的成语。由于缺乏独特的视觉模式,你必须多做一些研究才能知道它与if( var == 0)不一样。这是一个很薄的区别,但值得一提。存在if( 0 != var )样式的事实给出了可信度。最好只是消除问题并使用if( var )来保证真实性。

其次,更重要的是,意图必须明确。您是在测试真相还是在测试一些(或缺少)? if( var )正在测试真相,if( var != 0 )正在测试一个数字。要确定任何其他内容需要了解作者的风格,我们必须假设维护程序员没有。

第三,这里假设真假和数字运算符的值可能在某些语言中有效而在其他语言中没有。在Perl中,我认为Javascript也是空字符串是假的。很多运算符返回空字符串为false。因此,使用if( var != 0 )测试真相会导致警告。当你做一些像if( var == 1 )更天真的事情来表达真理时,它会变得更加明显,这是一个明显危险的假设。我似乎有很多初级程序员写这个,然后编写函数返回奇数但真实的数字来惩罚这类事情。或者当我心情愉快的时候,我用return var ? 1 : 0清理了我的回报值。

在相关的说明中,Perl将从子例程返回最后一个计算的表达式,因此不必实际编写return。将此与人们认为明确的return较慢的想法相结合,你会让很多人滥用这个事实。

sub set {
    my( $self, $key, $value ) = @_;

    $self->{$key} = $value;
}

set将返回$value。这是有意的吗?我不知道。我所知道的是有人会开始依赖它。维护程序员不知道他们是否可以改变它。所以我喜欢在每个非平凡的子程序中明确地给出一个返回值。

sub set {
    my( $self, $key, $value ) = @_;

    $self->{$key} = $value;
    return;
}

在这种情况下,我决定set暂时不会返回任何内容,而且对于读者和用户来说,这个决定都会非常明确。

答案 3 :(得分:18)

if (var)

少输入,只要你确定你没有测试错误的东西。

答案 4 :(得分:13)

我更喜欢显式测试,除非括号内的结果是显式布尔值。短语“if(1)”虽然在语法上在语法和语义上是正确的,但却不符合逻辑。它应该是真或假,不是自动投射。

我更喜欢可读的逻辑代码,以减少任何一天的输入。

我也鄙视形式的强烈代码:

if (gotError == FALSE) ...
if (isComplete == TRUE) ...

如果布尔值被正确命名(它应该是),那么正确的方法是:

if (!gotError) ...
if (isComplete) ...

那是因为(使用reductio ad absurdum)boolVal == TRUE只是另一个布尔值,所以你在哪里停止?

if (isComplete == TRUE) ...
if ((isComplete == TRUE) == TRUE) ...
if (((isComplete == TRUE) == TRUE) == TRUE) ...
if ((((isComplete == TRUE) == TRUE) == TRUE) == TRUE)...

依此类推,无限无休。

答案 5 :(得分:9)

我想说如果你比较一个真正的整数,那么永远不要隐式转换为布尔值,因为它意味着变量的含义不同。

但是那种风格如此受欢迎可能并不是什么大不了的事,但是从我与C#的合作中,我用这种风格编写了我的C ++代码:

布尔值或int,它基本上是一个布尔值:

if (val)

超过真/假的真整数很重要:

if (val != 0)

某种指针:

if (val != NULL)

但是很多人会说编码样式没有任何功能差异,所以最好保持一致,如果你正在处理现有代码,那就要与代码保持一致。

答案 6 :(得分:7)

Perl if (defined $var and $var ne '')if( $var)不等同。试试$var=0。相反,如果您在$var!=0上进行测试,那么所有无法转换为数字的字符串都将无法通过测试(如果您打开它们会发出警告)。

因此,您必须确切知道您的变量包含的内容(数字或字符串,是否可以undef),以便您可以进行相应的测试。

我通常只写if( $var)并让Perl照顾它。我相信这更容易阅读,这是Perl中最常见的风格。

实际上,通常,正确的测试最终为if( defined $var)。这就是perl的新(5.10)//运算符派上用场的地方。 $var= $val // $default$var //= $default$var仅在$default(resp $val)为$var时才会收到undef

答案 7 :(得分:4)

在Javascript中(我不知道其他动态语言)

if (x) 

if (x != 0)

意思是不同的东西。当我期望x保持对不应该为零长度的对象或字符串的引用时,我将使用前者。它是一个众所周知的习语。

答案 8 :(得分:3)

如果你有一个布尔值,你应该感觉很舒服:

if ( var )
if ( $var )

如果您对“布尔值”有更多特定要求,您可以随时对变量进行一些准备工作/测试,并将其分配给具有更好定义布尔值的另一个变量。

$shouldDoSomething = ( defined $var and $var ne '' ) ? 1 : 0;

if ( $shouldDoSomething ) {
    // Handle this case.
}

这可以清理代码。如果您打算多次使用此条件,它也会有所帮助。实际上,我发现这种情况经常发生。另外,我觉得上面的内容比内联更具可读性:

if ( defined $var and $var ne '' ) {
    // Handle this case.
}

答案 9 :(得分:3)

对于数字值标量,当if ( $num_foo )在我的控制范围内时,我倾向于写$num_foo。如果是用户输入或从外部传入,我要先将其编号或明确说明测试。这取决于很多因素。主要标准是何时以及如何处理未定义的值,以避免警告。

为了测试非空字符串,我曾经写过if ( $foo ),因为正确的咒语太多了:

if ( defined $foo and length $foo )

但是我对这种状态感到不满意I instigated a change of behaviour for length undef in Perl 5.12,它会发出警告并返回0到Perl 5.10(含)。 In 5.12 it will just silently return undef。因此,在非布尔上下文中,您仍会收到警告,它只是在评估length调用之后而不是之前发生。但是在布尔上下文中,没有警告,因此检查非空字符串更容易正确执行:

if ( length $foo )

答案 10 :(得分:3)

我像大多数人一样具有可读性,我喜欢能够扫描我的代码并阅读它而不必过多考虑,但它具有良好命名的变量名称。如果你的变量名称听起来应该是普通if(isPurchasable),那么我会使用它,但是它引用了我使用if(stock > 0)的数字或日期或类似的情结。

如果表达式如此简单,那么我必须为if语句编写注释是一个可怕的想法,如下所示的if语句虽然我可以看到为什么应该使用注释。

if(isPurchasable && stock > 0 && credit >= cost && !reserved) { 
     // Checks to see if customer can purchase product.
}

答案 11 :(得分:2)

如果if (var)用作布尔值,我通常更喜欢if ($var)var,即使语言中没有任何此类类型。

我非常不喜欢像if (!strcmp(...))if (var == true)这样的结构。第一个尝试太聪明,第二个太愚蠢 - 虽然它可以很好地扩展到if ((var == true) == true),......; - )

某些语言(如Perl和C ++)提供额外甚至用户定义的真实性解释。如果转换为布尔值似乎太神奇了,请记住它基本上只是一个is_true(var)var.booleanValue(),或类似于幕后的东西,只是一种更简洁的语法。

与您的问题相关,我希望以积极的方式制定条件。而不是

if (!condition) {
    g();
}
else {
    f();
}

我更喜欢

if (condition) {
    f();
}
else {
    g();
}

即使只有一个分支,条件也不是非常简单。 (这表明需要发表评论。)例如,而不是

// explain reason for condition here
if (!condition) {
    f();
}

我更喜欢将其标记为

if (condition) {
    // explain condition here
}
else {
    f();
}

答案 12 :(得分:2)

我并不总是管理它,但我尝试使用

if (0 != var)

所以它符合防守风格

if (0 == var)

答案 13 :(得分:2)

以我的思维方式,简单是最好的。

您制作代码越简单越好。此外,你犯错的可能性也越小。因此,我会用

if(var)

但最后,你应该使用最符合你自己思维方式的东西。

答案 14 :(得分:2)

在C#中,编写

明确是非法的
if(x){}

除非x是布尔类型。大多数其他类型都没有隐式转换为bool。

我使用这个表单编写JavaScript,PHP等等来检查非null。但话说回来,我确实从中获得了一些(容易检测到的)错误...我想如果没有它我们会更好。

在布尔变量上使用它时,我坚信易于理解的名称。我通常将布尔变量命名为使用名称以“is”,“has”或类似名称开头的布尔变量。

答案 15 :(得分:2)

我很惊讶没有人提到另一种选择,我的过去雇主的编码标准提倡:

if( 0 != x );

常量始终列在第一位(尤其是比较更重要,因为它们偶尔会被错误地分配 - 许多错误的来源)

这是我以来在C / Perl / C ++ / VB.Net中使用过的风格(显然,这一点在C#中没有实际意义,实际上不允许if (x)场景(除非x实际上是当然是布尔值。

答案 16 :(得分:2)

我有很多方法可以做到:

对于布尔人:

if (x)
对于整数来说

if (x != 0)  // always compare, never assume true/false on int values

指针:

if (x /* != 0 */)  // I've always done this, not sure where I picked it up but I like it

现在,我认为有一个函数调用更好,它描述了if语句中逻辑的实际含义

编辑:注意,0(intsead为NULL)是因为我这些天主要使用C ++

答案 17 :(得分:1)

我更喜欢裸露的:

if ($canDo) {
}

而不是像:

if ($canDo == true) {
}

如果条件变得棘手,我会用注释明确地注释它,或者用一个好的变量名来隐式注释它。在设置布尔变量时我也会尝试非常明确,更喜欢:

my($canDo) = !0;

my($canDo) = 1;

后者令人困惑;为什么要给布尔值赋一个离散值?

鉴于Perl的“评估为真”的许多含义,我可以看到为什么从长远来看,更明确的更为实用。尽管如此,我最喜欢Perl的一个原因是它的自然语言流动性,我更喜欢在我的代码中坚持这一点(如果需要,请留下评论和变量名称以进一步澄清事物)。

答案 18 :(得分:1)

如果你已经在C中拥有一个已经拥有一个标志(而不是一个计数)的int-bool,并且你用“if(var!= 0)”进行测试,它在哪里结束? “if((var!= 0)!= 0)”会不会更好? : - )

答案 19 :(得分:0)

我经常使用:

 if(x) {
       DoSomething;
       DoSomething2;
     }

因为这不是写作,所以读书说:

  

很少有优秀的程序员使用 if(x!= 0),他们使用 if(x)

但有时使用和其他形式:

if(x!=0) 

HNY! : - )

答案 20 :(得分:0)

的VBScript?那么这段代码声明了一个Variant,所以bFlag为零,实际上是一个False。

Dim bFlag
If bFlag Then

我不喜欢那样。因此,即使在VB中,通过选择更具体的声明,无论类型如何,我都会发现自己是明确的。

Dim bFlag As Boolean
If bFlag = False Then

另一个与变量命名规则有关的问题。如果您正在使用受匈牙利影响的政权,那么您可以直观地判断给定变量是否为布尔值,因此具体关于它是真还是假不是问题。但是,如果您正在使用其他一些变量命名技术,或者更糟糕的是,以特殊方式命名,那么具体说明正在测试的内容是合适的。

答案 21 :(得分:0)

我发现if(X){/ * ... * /}更容易阅读(至少在C中)。

答案 22 :(得分:0)

如果我不指望其他人阅读这些代码,我就是我们的简短代码。 如果我希望有人真正阅读我的代码,我会考虑使用长格式来提高可读性。

答案 23 :(得分:0)

在我看来,if (var != 0)更好。

答案 24 :(得分:0)

我喜欢Python构造:

if var:
    return "I like the way I do it!"

仅举例来说; - )

答案 25 :(得分:0)

有些语言你别无选择。例如,在Specman中,你不能写:

var x: uint;

if (x) {
    bla
};

但你可以做:

var x: uint;

if (x != 0) {
    bla
};

var x: bool;

if (x) {
    bla
};

但是,你做不到:

var x: bool;

if (x != 0) {
    bla
};

因为你无法将布尔值与整数进行比较。

来自C和Perl我一直觉得这很烦人,直到我真的开始在Specman写了很多东西。代码就像这样简单明了。