2011-02-10 2 views
1

Я пытаюсь создать массив массивов, а затем ссылаюсь на них.perl - проблема с пониманием массива массивов

Я делаю somethign как:

sub foobar 
{ 
my @array; 
my $i; 
for ($i = 0; $i < 1000; $i=$i+1) 
{ 
    my @row; 
    $row[0] = $i; 
    $row[1] = foo($bar); 
    push @array , [@row]; 
} 
return \@array; 
} 

я могу добраться до значений с помощью:

$array->[x]->[y]; 

Однако я не понимаю, почему второй -> нужен. $ array -> [x] Я понимаю, потому что $ array является ссылкой. Но не $ array -> [x] означает массив? Почему это не работает:

my @notarray = $array->[x]; 

Что точно не заполнено массивом сейчас? Поскольку он определенно не является массивом, содержащим $ i, foo ($ bar)

Как бы $ array -> [x] -> [y] отличался для ссылки на массив ссылок на массивы ?

ответ

4

Второй -> не нужен, на самом деле.

Здесь заключено соглашение: все значения массива Perl и значения хэша должны быть скалярами. Это означает либо строку, число, либо массив/хеш-ссылку (а не простой старый массив или хэш).

Итак, первый оператор -> разыгрывает массив и попадает в строку x'th. В нем есть не массив, а массив. Поэтому, чтобы добраться до данных там, вам теоретически понадобится еще один оператор ->.

Но получите это. Perl умный: он знает, что после одного массива или хеш-доступа, если происходит другой доступ, единственный способ, которым это возможно, - это использовать массив/хеш-ссылку (потому что ваш первый массив/хэш-доступ ДОЛЖЕН возвращать скаляр)! Так что вам не нужна вторая стрелка.

Для получения более подробной информации см. perldata.

+0

Спасибо, по какой-то причине я пришел к выводу, что возможно иметь массивы массивов, но они действительно массивы ссылок. – kiasectomondo

2

Когда вы

push @array, [@row]; 

вы толкаете ссылка на массив. Это необходимо из-за правила Perl, что массивы сглажены. Таким образом, $ array -> [x] является ссылкой на массив строк, а не на массив строк. Однако между индексами стрелка необязательна. Так $array->[x]->[y] точно так же, как и $array->[x][y] (который является точно такой же, как ${$array}[x][y] и т.д.)

Все это объясняется в Perl reference tutorial

+0

Если я нажимаю ссылку, то почему каждая строка по-прежнему отличается? Разве они не должны ссылаться на одно и то же? – kiasectomondo

+1

@kiasectomondo: Вы создаете новую анонимную ссылку каждый раз. Если вы просто нажимаете '\ @ array' каждый раз (для того же' @ array'), который будет ссылаться на одно и то же. –

+1

@kiasectormondo => Строки будут ссылаться только на одно и то же, если вы объявили массив '@ row' вне цикла и взяли ссылку на него через' \ @ row'. Синтаксис '[@row]' создает мелкую копию массива и возвращает новую ссылку. В вашем случае, поскольку вы объявляете 'my @ row' внутри цикла, вы можете просто использовать' \ @ row', и он будет работать нормально. –

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