在 Perl 中,有什么区别
$status = 500;
和
$status = '500';
不多。他们都给五百分$status
。最初使用的内部格式会有所不同(IV 与 PV,UTF8=0),但这对 Perl 来说并不重要。
但是,根据存储格式的选择,有些事情的行为会有所不同,即使它们不应该这样做。根据存储格式的选择,
&
,|
和^
) 猜测它们的操作数是否为字符串。open
和其他与文件相关的内置函数是否使用 UTF-8 对文件名进行编码。(漏洞!)正如@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";
如果您随后$var
在对字符串或数字进行操作时使用具有不同风格的少数运算符之一,则只有区别:
$string = '500';
$number = 500;
print $string & '000', "\n";
print $number & '000', "\n";
输出:
000
0
为了提供更多关于“不多”响应的上下文,这里是通过 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
第一个是一个数字(499 到 501 之间的整数)。第二个是字符串(字符“5”、“0”和“0”)。他们之间没有区别是不正确的。一个会立即转换为另一个是不正确的。确实,字符串在必要时会转换为数字,反之亦然,转换大多是透明的,但并不完全。
答案何时字符串和数字之间的区别在 Perl 5 中涵盖了它们不等价的一些情况:
$x = 1000000000000000
然后$y = "1000000000000000"
$x 可能会字符串化为1e+15
. 由于使用变量作为哈希键是字符串化的,这意味着$hash{$x}
并且$hash{$y}
可能是不同的哈希槽。~~
) 和 given/when 运算符将数字参数与数字字符串区别对待。无论如何,最好避免使用这些运算符。我认为这完美地说明了正在发生的事情。
$ 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
),因此标量值有三种可能的表示。
内部有不同:)
($_ ^ $_) ne '0' ? print "$_ is string\n" : print "$_ is numeric\n" for (500, '500');
输出:
500 is numeric
500 is string
这个问题已经有很多答案了,但我会为困惑的新手试一试:
my $foo = 500;
my $bar = '500';
因为它们是,对于实际的pourpose,它们是“相同的”。有趣的部分是当您使用运算符时。例如:
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 比较字符串是否相等。
您可以尝试“^”运算符。
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 。