В Perl, какая разница между
$status = 500;
и
$status = '500';
В Perl, какая разница между
$status = 500;
и
$status = '500';
Не много. Они оба назначают пятьсот до $status
. Используемый внутренний формат будет отличаться первоначально (IV vs 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:
[email protected] ~ $ 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, делающий то, что вы имеете в виду:
[email protected] ~ $ 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}
могут быть разными слотами хеша.~~
) и заданные/когда обрабатывают аргументы числа, отличные от числовых строк. Лучше всего избегать этих операторов.Существуют разные внутренние функции:)
($_ ^ $_) ne '0' ? print "$_ is string\n" : print "$_ is numeric\n" for (500, '500');
выход:
500 is numeric
500 is string
Я думаю, это прекрасно демонстрирует, что происходит.
$ 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
), поэтому существует три возможных представления скалярного значения.
Много ответов уже на этот вопрос, но я дам ему шанс для путаного новичка:
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
В этом случае он ведет себя как atoi() в C. Он берет большую числовую часть, начиная с левой и использует ее как число. Если номеров нет, он использует их как 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';
}
. Я обычно использую этот оператор, чтобы рассказать разницу между num и str в perl.