你更喜欢“if(var)”还是“if(var!= 0)”?
我已经用C语言编程了几十年了。 在某个地方,我决定不再想写:
if (var) // in C if ($var) # in Perl
当我的意思是:
if (var != 0) if (defined $var and $var ne '')
我认为部分原因是我有一个强类型的大脑,在我看来,“if”需要一个布尔表达式。
或者也许是因为我使用Perl这么多,Perl中的真相和虚假就是这样一个雷区。
或者也许只是因为这些天,我主要是一名Java程序员。
你有什么偏好?为什么?
当我大声朗读时,我喜欢我的理解:
if (is_it_happening) ... if (number_of_sheep != 0) ... if (pointer_to_something != NULL) ...
我更喜欢
if (var != 0)
它更容易阅读/理解。 由于您只编写了一次代码但是阅读了很多次,因此简单易读比简单编写更重要。
这很简单。 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 != 0 )
会导致警告。 当你做一些更天真的事情时会变得更加明显, if( var == 1 )
表示真理,这是一个明显危险的假设。 我似乎有很多初级程序员写这个,然后编写函数返回奇数但真实的数字来惩罚这类事情。 或者当我心情愉快时,我用return var ? 1 : 0
清理了我的返回值return var ? 1 : 0
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
将暂时不返回任何内容,并且该决定将对读者和用户都非常清楚。
if (var)
少打字,只要你确定你没有测试错误的东西。
我更喜欢显式测试,除非括号内的结果是显式布尔值。 短语“if(1)”虽然在语法上在语法和语义上是正确的,但却不符合逻辑。 它应该是真或假,不是自动投射。
我喜欢可读的逻辑代码,以减少任何一天的输入。
我也鄙视forms的强烈代码:
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)...
等等,无限的。
我会说如果你比较一个真正的整数,那么永远不要隐式转换为布尔值,因为它意味着变量具有不同的含义。
但是那种风格如此受欢迎可能并不是一件大事,但是从我对C#的工作中,我用这种风格编写了我的C ++代码:
布尔或int基本上是布尔值:
if (val)
超过真/假的真整数很重要:
if (val != 0)
某种指针:
if (val != NULL)
但是,正如许多人会说的那样,编码样式没有任何function差异,最好是保持一致,如果你正在使用现有的代码,那么就要与代码保持一致。
在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
只有在$val
(resp $var
)为undef
才会收到$default
。
在Javascript(我不知道其他动态语言)
if (x)
和
if (x != 0)
意思不同。 当我期望x持有对不应该为零长度的对象或字符串的引用时,我将使用前者。 它是一个众所周知的成语。
如果你有一个布尔值,你应该感觉很舒服:
if ( var ) if ( $var )
如果对“boolean”有更多特定要求,则可以随时对变量进行一些准备工作/测试,并将其分配给具有更好定义的布尔值的另一个变量。
$shouldDoSomething = ( defined $var and $var ne '' ) ? 1 : 0; if ( $shouldDoSomething ) { // Handle this case. }
这可以清理代码。 如果您打算多次使用此条件,它也会有所帮助。 实际上,我发现这种情况经常发生。 另外,我觉得上面的内容比内联更具可读性:
if ( defined $var and $var ne '' ) { // Handle this case. }
我像大多数人一样具有可读性,我喜欢能够扫描我的代码并阅读它而不必过多考虑,但它具有良好命名的变量名称。 如果你的变量名称听起来像它应该是一个普通的if(isPurchasable)
然后我去它然而它引用一个数字或日期或类似的fasion我使用if(stock > 0)
。
如果表达式如此简单,那么我必须为if语句编写注释是一个可怕的想法,如下所示的if语句虽然我可以看到为什么应该使用注释。
if(isPurchasable && stock > 0 && credit >= cost && !reserved) { // Checks to see if customer can purchase product. }
对于数值标量,当$num_foo
在我的控件中时,我倾向于写if ( $num_foo )
。 如果是用户输入或从外部传入,我要先将其编号或明确说明测试。 这取决于很多因素。 主要标准是何时以及如何处理未定义的值,以避免警告。
为了测试非空字符串,我曾经写过if ( $foo )
因为正确的咒语太多了:
if ( defined $foo and length $foo )
但是我对这种状况并不满意所以我在Perl 5.12中发起了一个length undef
的行为改变 ,它会抛出一个警告并返回0到Perl 5.10(含)。 在5.12中,它将默默地返回undef
。 因此,在非布尔上下文中,您仍然会收到警告,它只是在评估length
调用之后而不是之前发生。 但是在布尔上下文中,没有警告,因此检查非空字符串更容易正确执行:
if ( length $foo )
我有很多方法可以做到:
对于布尔值:
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 ++
我很惊讶没有人提到另一个选项,我的过去雇主的编码标准提倡:
if( 0 != x );
常量总是首先列出的位置(尤其是比较更重要,因为它们偶尔会被错误地分配 – 许多错误的来源)
这是我在C / Perl / C ++ / VB.Net中使用过的风格(显然这一点在C#中没有实际意义,实际上不允许使用if (x)
场景(除非x实际上是一个布尔值,课程)。
在C#中,它被明确写成非法
if(x){}
除非x是布尔类型。 大多数其他类型没有隐式转换为bool。
我使用这个表单编写JavaScript,PHP等等来检查非null。 但话说回来,我确实从它那里得到了一些(容易发现的)错误…我想如果没有它我们会更好。
在布尔变量上使用它时,我坚信易于理解的名称。 我通常将布尔变量命名为使用名称以“is”,“has”或类似名称开头的布尔变量。
如果使用var
作为布尔值,我通常更喜欢if (var)
或if ($var)
,即使语言中没有任何这样的类型。
我非常不喜欢if (!strcmp(...))
或if (var == true)
。 第一个尝试太聪明,第二个太愚蠢 – 虽然它很好地扩展到if ((var == true) == true)
,… 😉
某些语言(如Perl和C ++)提供了额外的甚至是用户定义的真实性解释。 如果转换为布尔值似乎is_true(var)
,请记住它基本上只是一个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(); }
按照我的想法,简单是最好的。
你制作代码越简单越好。 而且,你犯错的可能性也越小。 因此,我会用
if(var)
但最终,你应该使用最适合自己思维方式的东西。
我并不总是管理它,但我尝试使用它
if (0 != var)
所以它符合防守风格
if (0 == var)
如果你在C中有一个int-bool已经拥有一个标志(而不是一个计数),并且你用“if(var!= 0)”测试它,那么它在哪里结束? “if((var!= 0)!= 0)”会不会更好? 🙂
我更喜欢裸露的:
if ($canDo) { }
而不是像:
if ($canDo == true) { }
在条件完全棘手的情况下,我会用注释明确地评论它,或者用一个好的变量名称隐式地评论它。 设置布尔变量时我也会尝试非常明确,更喜欢:
my($canDo) = !0;
至
my($canDo) = 1;
后者令人困惑; 为什么要给布尔值赋一个离散值?
鉴于Perl的“评估为真”的许多含义,我可以看出为什么从长远来看,更明确的更为实用。 尽管如此,我最喜欢Perl的一个原因是它的自然语言流动性,我更喜欢在我的代码中坚持这一点(如果需要的话,留下评论和变量名称以进一步澄清事物)。
VBScript的? 那么这段代码声明了一个Variant,所以bFlag为零,实际上是一个False。
Dim bFlag If bFlag Then
我不喜欢那样。 因此,即使在VB中,通过选择更具体的声明,无论类型如何,我都会发现自己是明确的。
Dim bFlag As Boolean If bFlag = False Then
另一个问题与变量命名规则有关。 如果您正在使用受匈牙利影响的政权,那么您可以直观地判断给定变量是否为布尔值,因此具体关于它是真还是假不是问题。 但是,如果您正在使用其他变量命名技术,或者更糟糕的是,以特殊方式命名,那么具体说明正在测试的内容是合适的。
我经常使用:
if(x) { DoSomething; DoSomething2; }
因为这写作较少,并且预订哪个阅读说:
很少有优秀的程序员使用form if(x!= 0) ,他们使用if(x) 。
但有时使用和其他forms:
if(x!=0)
HNY! 🙂
我发现if(X){/ * … * /}更容易阅读(至少在C中)。
如果我不指望其他人阅读这些代码,我就是我们的简短代码。 如果我希望有人真正阅读我的代码,我会考虑使用长格式来提高可读性。
我喜欢Python结构:
if var: return "I like the way I do it!"
这只是例如 😉
有些语言你别无选择。 例如,在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写了很多东西。 代码就像这样简单明了。
在我看来, if (var != 0)
更好。