2017-02-16 30 views
1

Я просто пытался объединить массивы в Perl с оператором + и получил странные результаты:Почему конкатенация массивов в Perl дает номера?

perl -wE 'say([1, 2, 3] + [4, 5, 6])' 
73464360 

делает то же самое с хэшей, кажется, ошибка синтаксиса:

perl -wE 'say({} + {})' 
syntax error at -e line 1, near "} +" 
Execution of -e aborted due to compilation errors. 

Что является результатом первое выражение? Документировано ли это где угодно?

+3

Что заставило вас думать, что это сработает? –

+2

Запустите 1-ю команду много раз; вы получаете разные результаты? – toolic

+0

@Mark: мои привычки питона .. – planetp

ответ

7

Это из числа ссылок, которые выдает адрес памяти ссылки.

perl -E 'say \@a; say 0+\@a; printf "%x\n",0+\@a' 

Типичный выход (хотя это может меняться каждый раз при запуске программы)

ARRAY(0x1470518) 
21431576 
1470518  <--- same number as in first line 

Ваш хэш ссылки пример почти работает, но это, кажется, что Perl является разбор первого набора {} блоков в качестве кода, а не как хеш-ссылку. Если вы используете унарный + и заставляете Perl относиться к нему как к хеш-ссылке, он будет работать. Я имею в виду «работу».

perl -E 'say(+{} + {})' 
40007168 
+4

Да.Когда он видит 'say ({', он думает, что вы используете синтаксис 'say BLOCK LIST' (который используется для' say {$ handleles {$ x}} "foo"; ') – ikegami

3

Потому что + в Perl является только арифметическим оператором. Это заставляет его аргументы интерпретировать как числа, несмотря ни на что. Вот почему Perl имеет отдельный оператор для конкатенации строк (.).

Что вы делаете, эффективно добавляет адреса, где хранятся массивы.

Конкатенация массива выполняется путем простого перечисления массивов один за другим. Однако, если вы используете ссылки на массивы ([ ... ]), то вам придется разыменованием их первым с @{ ... }:

perl -wE 'say(@{[1,2,3]}, @{[4,5,6]})' 

Но обычно вы будете использовать массив переменные и не требуется дополнительное синтаксис.

perl -wE 'my @a = (1,2,3); my @b = (4,5,6); say join("-",@a,@b)' 
#=> 1-2-3-4-5-6 

То же самое относится к хешам; my %c = (%a,%b); объединит содержимое %a и %b (в таком порядке, чтобы значение %b для любых распространенных ключей переписало %a) в новый хеш %c. Вы можете использовать my $c = { %$a, %$b };, чтобы сделать то же самое со ссылками. Один полученный, который вы используете в своей попытке +, заключается в том, что {} может быть интерпретирован как пустой блок кода вместо пустого хэша.