2013-06-27 4 views
28

В Perl, в чем разница между

$status = 500; 

и

$status = '500'; 
+4

Возможный дубликат [Когда разница между строкой и числом в Perl 5?] (Http://stackoverflow.com/questions/2980550/when-does-the-difference-between-a-string- and-a-number-matter-in-perl-5) –

+0

Если статус является числовым, назначьте номер. Если это строка, назначьте строку. Обратите внимание, что строка, состоящая только из цифр, необязательно является числовой величиной (как в «номере социального страхования»). – Ingo

ответ

39

Не так много. Они оба назначают пятьсот до $status. Используемый внутренний формат будет отличаться первоначально (IV vs PV, UTF8 = 0), но это не имеет значения для Perl.

Однако есть вещи, которые ведут себя по-разному в зависимости от выбора формата хранения, хотя они и не должны. Основываясь на выборе формата хранения,

  • JSON решает, использовать ли цитаты или нет.
  • DBI угадывает тип SQL, который он должен использовать для параметра.
  • Побитовые операторы (&, | и ^) предполагают, являются ли их операнды строками или нет.
  • open и другие связанные с файлами встроенные имена кодируют имя файла с использованием UTF-8 или нет. (Ошибка!)
  • Некоторые математические операции возвращают отрицательный ноль или нет.
+2

Если вы передадите это число через конструктор JSON, вы получите «500», а другой выведет 500 – alexk

+1

@alexk, см. Обновление. – ikegami

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+, e.г:

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

Удивительный ответ. Я сохраню в моей папке и папке с предметами perl. – ado

+3

. Кажется, это не имеет никакого отношения к вопросу, чтобы быть выбранным ответом. IMO – plusplus

+0

Пожалуйста, не начинайте никаких фламвар.(Мое знание perl - это всего лишь доля знаний Икегами (и других) - только пробовала помощь с моего «уровня». Как сказал пульсплюс - это, вероятно, оффтоп. Извините за это. – jm666

19

Существует только разница, если вы затем использовать $var с одним из немногих операторов, который имеет разные вкусы при работе на шнурке или номер:

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

выход:

000 
0 
+0

Это кажется самым практичным ответом на меня. –

8

Чтобы предоставить немного больше контекста для ответов «не очень», здесь представлено представление внутренних структур данных двух значений через модуль 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 
3

Есть разные внутри :)

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

выход:

500 is numeric 
500 is string 
6

Первый число (целое число между 499 и 501). Вторая строка (символы «5», «0» и «0»). Это не верно, что между ними нет никакой разницы. Это не верно, что он будет немедленно преобразован в другой. Он равен true, что строки при необходимости преобразуются в номера и наоборот, а преобразование в основном прозрачно, но не полностью.

Ответ 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} могут быть разными хеш-слотами.
  • Умное совпадение (~~) и заданные операторы /, если операторы обрабатывают аргументы числа, отличные от числовых строк. Лучше избегать этих операторов.
2

Многие ответы уже на этот вопрос, но я дам ему выстрелили в запутанном новичку:

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

Поскольку они, по практическим pourposes они являются «же». Интересная часть - когда вы используете операторов. Например:

print $foo + 0; 

output: 500 

Знак '+' оператор видит ряд на его левой и ряд в своем праве, как десятичные, следовательно, ответ 500 + 0 => 500

print $bar + 0; 

output: 500 

Same вывода оператор видит строку, которая выглядит как десятичное целое слева, а справа - ноль, поэтому 500 + 0 => 500

Но где различия? Это зависит от используемого оператора. Операторы решают, что произойдет. Например:

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

В этом случае он ведет себя как 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 сравнивает строки для равенства.

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), поэтому существует три возможных представления скалярного значения.

0

Вы можете попробовать "^" оператор.

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

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

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

$ str^$ str отличается от $ num^$ num, поэтому вы получите «хе-хе». пс "^" изменит аргументы, так что вы должны сделать

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

. Я обычно использую этот оператор, чтобы рассказать разницу между num и str в perl.

Смежные вопросы