【问题标题】:Do you prefer "if (var)" or "if (var != 0)"? [closed]你更喜欢“if (var)”还是“if (var != 0)”? [关闭]
【发布时间】:2010-09-29 02:58:02
【问题描述】:

几十年来,我一直在使用 C 派生语言进行编程。在某个地方,我决定不再想写:

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

当我的意思是:

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

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

或者可能是因为我使用 Perl 太多,而 Perl 中的真假是一个雷区。

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

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

【问题讨论】:

  • 说真的,我不明白,这是一个有用的问题吗?答案中的教条式讲道让我很生气(主要是因为我不同意)!如果你有 5 次代表和写英语的困难,它会不加思索地被关闭。
  • 我只是想看看人们对此类问题的看法,以及他们是否对此深思熟虑。这个问题已经一年多了。 SO在那段时间里发生了很大的变化。你是对的:现在有很多关于 SO 的教条式讲道 - 似乎没有多少“活着,让我们活着” - 我不得不想知道这些想法有多大的代表性。跨度>

标签: c perl coding-style


【解决方案1】:
if (var)

只要你确定你没有测试错误的东西,就不用打字了。

【讨论】:

  • 不仅打字少,阅读也少,这意味着理解它需要更少的脑力。
  • if(v) 键入和阅读的击键次数减少了 3 次,所以效果要好得多。
  • 这都是关于语义的 问我的妻子她会很难过两种方式都不可读(她不是程序员)对于训练有素的 C 编码器非常清楚,所以我也更喜欢简短的方式。
  • @PolyThinker,这不是真的。
【解决方案2】:

我更喜欢

if (var != 0)

更容易阅读/理解。既然你写了一次代码,读了很多次,那么易读比易写更重要。

【讨论】:

  • 我使用这个,除非 var 是布尔值。如果 (var == true),我从不这样做。
  • if (var) 对我来说同样容易阅读(如果不是更容易的话)。多读意味着更难理解。但我同意这纯粹是主观的。
  • 我同意 PolyThinker... 对我来说,if(var) 更容易阅读,因为阅读量更少,而且我已经理解它的含义。
  • 警告:“少读意味着更容易理解”的理论不可避免地导致 APL 是最易读的计算机语言的结论。我们的测试另有说明。
【解决方案3】:

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

我更喜欢可读的逻辑代码,而不是每天少打字。

我也非常鄙视这种形式的代码:

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

如果布尔值被正确命名(并且应该如此),那么正确的做法是:

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

那是因为(使用归约法)boolVal == TRUE 只是另一个布尔值,所以你在哪里停下来?

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

以此类推,无穷无尽。

【讨论】:

    【解决方案4】:

    我有很多方法:

    对于布尔值:

    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(NULL 的整数)是因为我这些天主要使用 C++

    【讨论】:

    • 为什么要使用“if (x /* != 0 */)”?生成更少(因此更快)的代码? “if (x)”和“if (x != 0)”生成的代码有什么区别吗?
    • 可读性,比什么都重要。我年轻的时候做过一些辅导,这对新手有所帮助(如果(x))可能会令人惊讶地令人困惑。我总是对逻辑很小心 :-) 我认为它不会产生更少的代码,无论如何都不足以成为重要的 :-)
    【解决方案5】:

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

    Dim bFlag
    If bFlag Then
    

    我不喜欢那样。因此,即使在 VB 中,如果可以选择更具体的声明,我发现自己是明确的,无论是什么类型。

    Dim bFlag As Boolean
    If bFlag = False Then
    

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

    【讨论】:

      【解决方案6】:

      如果你有一个打算作为布尔值的值,你应该觉得这样做很舒服:

      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.
      }
      

      【讨论】:

      • 那个? 1 : 0 是不必要的,而且在我看来,是模糊的。
      • 你是对的,这个特定的例子是不必要的。我添加它是为了解决问题中提到的“Perl 中的真假”是“这样的雷区”问题。使用此代码,您会知道 $shouldDoSomething 将始终为 0 或 1。
      【解决方案7】:

      我喜欢我的ifs 在大声朗读时有意义:

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

      【讨论】:

      • LHS 上的常量请 :)
      • 左边的常数破坏了能够大声读出它的目的。
      • @Shy 0 != number_of_sheep(零不是羊的数量)对我来说听起来不错:P
      • 对于绝地大师来说,尤其如此。
      • 当编译器脑死亡时,LHS 上的常量是有意义的。现在,如果您尝试在 if 中进行分配,他们会标记警告,并且每个人都应该打开“将警告视为错误”。
      【解决方案8】:

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

      if (x) 
      

      if (x != 0)
      

      意思不同。当我希望 x 持有对不应为零长度的对象或字符串的引用时,我将使用前者。这是一个众所周知的成语。

      【讨论】:

        【解决方案9】:

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

        但话说回来,这种风格如此流行可能没什么大不了的,但是从我使用 C# 的工作来看,我以这种风格编写了我的 C++ 代码:

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

        if (val)
        

        大于真/假的真整数很重要:

        if (val != 0)
        

        某种指针:

        if (val != NULL)
        

        但正如许多人所说的那样,编码风格在功能上没有任何区别,最好保持一致,如果您正在使用现有代码,请与该代码保持一致。

        【讨论】:

          【解决方案10】:

          我经常使用:

           if(x) {
                 DoSomething;
                 DoSomething2;
               }
          

          因为这是少写的,而读的书说:

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

          但有时使用和其他形式:

          if(x!=0) 
          

          嘿嘿! :-)

          【讨论】:

          • 哪本书这么说的?
          【解决方案11】:

          我很惊讶没有人提到我以前雇主的编码标准所提倡的另一种选择:

          if( 0 != x );
          

          常量总是列在最前面(特别是在比较时更重要,因为它们偶尔会在分配中出现拼写错误——许多错误的根源)

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

          【讨论】:

          • 很想知道为什么有人不赞成这个...
          • 同意,反对的选民应该发表评论!
          • 今天也获得了另一个无法解释的反对票......
          • 它应该被否决,因为它离题了。 LHS 与 RHS 上的常数与如何测试布尔值是分开的。
          • LHS 上的常数是荒谬的,并假定其他编码人员和您自己缺乏智慧。
          【解决方案12】:

          在 C# 中,写法已被明确规定为非法

          if(x){}
          

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

          我经常使用这种形式编写 JavaScript、PHP 等来检查非空值。但话又说回来,我确实从中得到了一些(很容易检测到的)错误......我想没有它我们会更好。

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

          【讨论】:

            【解决方案13】:

            在 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,仅当$val(对应$var)是undef

            【讨论】:

            • 这就是为什么我说“Perl 中的真假是一个雷区”。我通常想知道的是是否“定义了 $var 和 $var ne ''”。我通常不希望测试返回 false if "$var eq '0'"
            【解决方案14】:

            如果var 用作布尔值,我通常更喜欢if (var)if ($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();
            }
            

            【讨论】:

              【解决方案15】:

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

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

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

              【讨论】:

              • 可读代码提高了代码的可维护性和理解性。代码是为人设计的。 IL 或二进制适用于计算机。
              • 不想想太多,你真的应该成为一名编码员吗!?
              • @James;好点,但不是我的意思;应该为手头的实际问题保留思考;如果简单地计算出我的代码在做什么需要思考,那么解决任何问题所花费的时间都是两倍。
              【解决方案16】:

              对于数值标量,当$num_foo 在我的控制范围内时,我倾向于写if ( $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 )
              

              【讨论】:

                【解决方案17】:

                在我看来,简单是最好的。

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

                if(var)
                

                但最后,您应该使用最适合您自己的思维方式的方法。

                【讨论】:

                  【解决方案18】:

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

                  if (0 != var)
                  

                  所以它符合防守风格

                  if (0 == var)
                  

                  【讨论】:

                    【解决方案19】:

                    我更喜欢裸露的:

                    if ($canDo) {
                    }
                    

                    而不是类似的东西:

                    if ($canDo == true) {
                    }
                    

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

                    my($canDo) = !0;
                    

                    my($canDo) = 1;
                    

                    后者令人困惑;为什么将离散值分配给布尔值?

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

                    【讨论】:

                      【解决方案20】:

                      这很简单。 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 也是,空字符串是错误的。许多运算符返回空字符串为假。因此,使用if( var != 0 ) 测试真相会导致警告。当你做一些像if( var == 1 ) 这样更天真的事情时,它会变得更加明显,这是一个明显危险的假设。我似乎有很多初级程序员写了这个,然后写了返回奇数但真实的数字的函数来惩罚这种事情。或者,当我心情好时,我已经用return var ? 1 : 0 清理了我的返回值。

                      在相关的注释中,Perl 将返回子程序中最后计算的表达式,因此实际上不必编写 return。将此与人们认为明确的return 更慢的想法相结合,您会得到很多人滥用这一事实。

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

                      set 将返回 $value。这是故意的吗?我不知道。我所知道的是有人会开始依赖它。维护程序员不知道他们是否可以更改它。所以我喜欢在每个重要的子程序中显式地添加一个 return。

                      sub set {
                          my( $self, $key, $value ) = @_;
                      
                          $self->{$key} = $value;
                          return;
                      }
                      

                      在这种情况下,我决定 set 暂时不会返回任何内容,并且该决定对读者和用户来说都很清楚。

                      【讨论】:

                      • 代码完成支持这个家伙。
                      • 我喜欢你的推理,从来没有这样想过。
                      • @nemo 我是在那本书上长大的。 :)
                      • +1 表示当子例程打算不返回任何内容时,您的习惯用法包括显式的 void 返回。我从来没有想过这个角度。顺便说一句,我最初的问题是“......当我的意思是如果 var != 0”,所以我并没有假设不同的形式是等价的,只是在某些情况下,为了更好的可读性,可以用另一种替换。
                      【解决方案21】:

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

                      【讨论】:

                        【解决方案22】:

                        如果我不希望其他人阅读代码,我会选择简短的。 如果我希望有人真正阅读我的代码,我会考虑使用长格式以提高可读性。

                        【讨论】:

                        • 有人总是会阅读代码。
                        【解决方案23】:

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

                        【讨论】:

                          【解决方案24】:

                          我喜欢 Python 结构:

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

                          只是举例 ;-)

                          【讨论】:

                            【解决方案25】:

                            如果您在 C 语言中有一个 int-bool 已经拥有一个标志(而不是一个计数),并且您正在使用“if (var != 0)”对其进行测试,那么它在哪里结束? “如果((var!= 0)!= 0)”不是更好吗? :-)

                            【讨论】:

                            • 有人一直在读哥德尔、埃舍尔和巴赫——或者跳过它直接读刘易斯卡罗尔:-)
                            • 我从来没有读过前者,也没有读过后者的任何东西。这是我大一的 CS 教授告诉我的。
                            • 好吧,我没说是 :-) 但我推荐他们俩。
                            【解决方案26】:

                            有些语言你别无选择。例如,在 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 编写很多东西。这样代码就更清楚了。

                            【讨论】:

                              猜你喜欢
                              • 2011-09-26
                              • 1970-01-01
                              • 2015-03-17
                              • 2014-12-01
                              • 2010-10-19
                              • 2011-08-15
                              • 1970-01-01
                              • 1970-01-01
                              • 2015-06-15
                              相关资源
                              最近更新 更多