【问题标题】:Difference between $var = 500 and $var = '500'$var = 500 和 $var = '500' 之间的区别
【发布时间】:2014-09-23 03:30:45
【问题描述】:

在Perl中,有什么区别

$status = 500;

$status = '500';

【问题讨论】:

标签: perl


【解决方案1】:

不多。他们都将五百分配给$status。最初使用的内部格式会有所不同(IV 与 PV,UTF8=0),但这对 Perl 来说并不重要。

但是,根据存储格式的选择,有些事情的行为会有所不同,即使它们不应该这样做。根据存储格式的选择,

  • JSON 决定是否使用引号。
  • DBI 猜测它应该用于参数的 SQL 类型。
  • 按位运算符(&|^)猜测其操作数是否为字符串。
  • open 和其他与文件相关的内置函数是否使用 UTF-8 对文件名进行编码。 (错误!)
  • 某些数学运算是否返回负零。

【讨论】:

  • 如果你通过 JSON 构造函数传递那个数字,一个会输出“500”,另一个会输出 500
【解决方案2】:

正如@ikegami 已经告诉的不多。但请记住,这里有很多区别

$ perl -E '$v=0500; say $v'

打印320(十进制值 0500 八进制数),并且

$ perl -E '$v="0500"; say $v'

打印什么

0500

$ perl -E '$v=0900; say $v'

什么会因错误而死:

Illegal octal digit '9' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

perl -E '$v="0300";say $v+1'

打印

301

但是

perl -E '$v="0300";say ++$v'

打印

0301

0x\d+类似,例如:

$v = 0x900;
$v = "0x900";

【讨论】:

  • 很棒的回复,我将保存在我的 perl details&thingies 文件夹中
  • 这似乎与 IMO 选择答案的问题有点无关
  • 请不要开始任何火焰战。 ;(我的 perl 知识只是池上(和其他人)知识的一小部分 - 只尝试了我的“水平”的帮助。正如 pulsplus 所说 - 这可能是题外话。对此感到抱歉。
  • @jm666,另外,4+4'4+4' 不同。这在有关插值的问题中出现了很多。
  • @cajwine,你说你不想知道内部细节。我完全同意这一点,这就是我没有进入他们的原因。但是你抱怨我没有详细介绍内部结构?我确切地提到了如果你想深入了解你需要研究的内容。你查过IV和PV吗? illguts 是一本好书。
【解决方案3】:

如果您随后将$var 与少数几个在对字符串或数字进行操作时具有不同风格的运算符之一一起使用,则只有区别:

$string = '500';
$number = 500;
print $string & '000', "\n";
print $number & '000', "\n";

输出:

000
0

【讨论】:

  • 这对我来说似乎是最实用的答案。
【解决方案4】:

为了提供更多关于“不多”响应的上下文,这里是通过 Devel::Peek 模块的两个值的内部数据结构的表示:

user@foo ~ $ perl -MDevel::Peek -e 'print Dump 500; print Dump "500"'
SV = IV(0x7f8e8302c280) at 0x7f8e8302c288
  REFCNT = 1
  FLAGS = (PADTMP,IOK,READONLY,pIOK)
  IV = 500
SV = PV(0x7f8e83004e98) at 0x7f8e8302c2d0
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,pPOK)
  PV = 0x7f8e82c1b4e0 "500"\0
  CUR = 3
  LEN = 16

这是按照您的意思执行的 Perl 转储:

user@foo ~ $ perl -MDevel::Peek -e 'print Dump ("500" + 1)'
SV = IV(0x7f88b202c268) at 0x7f88b202c270
  REFCNT = 1
  FLAGS = (PADTMP,IOK,READONLY,pIOK)
  IV = 501

【讨论】:

    【解决方案5】:

    第一个是数字(499 到 501 之间的整数)。第二个是字符串(字符“5”、“0”和“0”)。 不正确它们之间没有区别。 不正确一个会立即转换为另一个。确实字符串在必要时会被转换为数字,反之亦然,而且转换大多是透明的,但并不完全。

    答案When does the difference between a string and a number matter in Perl 5 涵盖了它们等效的一些情况:

    • 位运算符以数字方式处理数字(对每个数字的二进制表示的位进行操作),但它们按字符处理字符串(对每个字符串的每个字符的位进行操作)。
    • 即使是数字,JSON 模块也会将字符串输出为字符串(带引号),但它会将数字输出为数字。
    • 非常小或非常大的数字可能与您预期的不同,而字符串已经是字符串,不需要进行字符串化。也就是说,如果 $x = 1000000000000000$y = "1000000000000000" 则 $x 可能会字符串化为 1e+15。由于使用变量作为哈希键是字符串化的,这意味着$hash{$x}$hash{$y} 可能是不同的哈希槽。
    • 智能匹配 (~~) 和 given/when 运算符将数字参数与数字字符串区别对待。无论如何,最好避免使用这些运算符。

    【讨论】:

      【解决方案6】:

      内部有不同:)

      ($_ ^ $_) ne '0' ? print "$_ is string\n" : print "$_ is numeric\n" for (500, '500');
      

      输出:

      500 is numeric
      500 is string
      

      【讨论】:

        【解决方案7】:

        我认为这完美地说明了正在发生的事情。

        $ perl -MDevel::Peek -e 'my ($a, $b) = (500, "500");print Dump $a; print Dump $b; $a.""; $b+0; print Dump $a; print Dump $b'
        SV = IV(0x8cca90) at 0x8ccaa0
          REFCNT = 1
          FLAGS = (PADMY,IOK,pIOK)
          IV = 500
        SV = PV(0x8acc20) at 0x8ccad0
          REFCNT = 1
          FLAGS = (PADMY,POK,pPOK)
          PV = 0x8c5da0 "500"\0
          CUR = 3
          LEN = 16
        SV = PVIV(0x8c0f88) at 0x8ccaa0
          REFCNT = 1
          FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
          IV = 500
          PV = 0x8d3660 "500"\0
          CUR = 3
          LEN = 16
        SV = PVIV(0x8c0fa0) at 0x8ccad0
          REFCNT = 1
          FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
          IV = 500
          PV = 0x8c5da0 "500"\0
          CUR = 3
          LEN = 16
        

        每个标量 (SV) 可以有字符串 (PV) 和/或数字 (IV) 表示。一旦您在任何数字操作中使用仅具有字符串表示的变量,并且在任何字符串操作中使用仅具有数字表示的变量,它们就会同时具有两种表示形式。正确地说,还可以有另一种数字表示,浮点表示 (NV),因此标量值有三种可能的表示。

        【讨论】:

          【解决方案8】:

          这个问题已经有很多答案了,但我会为困惑的新手试一试:

          my $foo = 500;
          my $bar = '500';
          

          实际上,对于实际的浇注,它们是“相同的”。有趣的部分是当您使用运算符时。 例如:

          print $foo + 0;
          
          output: 500
          

          '+' 运算符在其左侧看到一个数字,在其右侧看到一个数字,均为小数,因此答案是 500 + 0 => 500

          print $bar + 0;
          
          output: 500
          

          同样的输出,操作员看到一个字符串,它的左边看起来像一个十进制整数,右边是一个零,因此 500 + 0 => 500

          但不同之处在哪里? 这取决于使用的运算符。运营商决定会发生什么。例如:

          my $foo = '128hello';
          print $foo + 0;
          output: 128
          

          在这种情况下,它的行为类似于 C 中的 atoi()。它从左侧开始获取最大的数字部分并将其用作数字。如果没有数字,则将其用作 0。

          在条件句中如何处理?

          my $foo = '0900';
          my $bar = 900;
          if( $foo == $bar)
          {print "ok!"}
          else
          {print "not ok!"}
          
          output: ok!
          

          == 比较两个变量中的数值。 如果您使用警告,它会抱怨将 == 与字符串一起使用,但它仍会尝试强制。

          my $foo = '0900';
          my $bar = 900;
          if( $foo eq $bar)
          {print "ok!"}
          else
          {print "not ok!"}
          
          output: not ok!
          

          eq 比较字符串是否相等。

          【讨论】:

            【解决方案9】:

            你可以试试“^”运算符。

            my $str  = '500';
            my $num  = 500;
            
            if ($num ^ $num)
            {
                print 'haha\n';
            }
            
            if ($str ^ $str)
            {
                print 'hehe\n';
            }
            

            $str ^ $str 与 $num ^ $num 不同,所以你会得到“呵呵”。 ps, "^" 会改变参数,所以你应该这样做

            my $temp = $str;
            if ($temp ^ $temp )
            {
                print 'hehe\n';
            }
            

            。 我通常用这个运算符来区分perl中的num和str。

            【讨论】:

              猜你喜欢
              • 2017-01-21
              • 1970-01-01
              • 2013-02-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多