$ var = 500和$ var ='500'之间的差异

时间:2013-06-27 00:47:18

标签: perl

在Perl中,

之间有什么区别
$status = 500;

$status = '500';

9 个答案:

答案 0 :(得分:39)

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

但是,根据存储格式的选择,有些事情表现不同,即使它们不应该。根据存储格式的选择,

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

答案 1 :(得分:21)

至于@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";

答案 2 :(得分:19)

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

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

输出:

000
0

答案 3 :(得分:8)

为了提供更多关于“不多”响应的上下文,这里是通过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

答案 4 :(得分:6)

第一个是数字(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}可能是不同的散列插槽。
  • 智能匹配(~~)和给定/何时运算符将数字参数与数字字符串区别对待。最好还是避免那些操作员。

答案 5 :(得分:3)

内部有不同:)

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

输出:

500 is numeric
500 is string

答案 6 :(得分:3)

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

$ 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),因此有三种可能的标量值表示。

答案 7 :(得分:2)

对于这个问题已经有很多答案,但我会为这个迷茫的新手提供一个镜头:

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比较字符串是否相等。

答案 8 :(得分:0)

您可以尝试“^”运算符。

my $str  = '500';
my $num  = 500;

if ($num ^ $num)
{
    print 'haha\n';
}

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

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

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

。 我通常使用这个运算符来告诉perl中num和str之间的区别。