Доступ к многомерным массивам Perl - PullRequest
0 голосов
/ 18 января 2019

Допустим, многомерный массив такой,

$myarray = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]];

Попытка получить к нему доступ тремя способами,

print $myarray->[1][1] #prints 5
print $myarray->[1]->[1] #also prints 5
print $myarray[1][1] #prints nothing

Я не могу понять разницу между первым и вторым типом доступа. В частности, второй является более явным, но все же первый работает. Это заставляет меня думать, что третья работа лучше (что я знаю, не будет, потому что myarray на самом деле является ссылкой, а не массивом).

Ответы [ 3 ]

0 голосов
/ 18 января 2019

$myarray->[1] означает «искать индекс 1 в массиве, используя ссылку на массив, сохраненную в $myarray».

$myarray[1] означает «поиск индекса 1 в массиве @myarray».

Две переменные $myarray и @myarray вообще не имеют связи.

0 голосов
/ 18 января 2019

Три очка

  1. $ myarray содержит ссылку на массив, а не на массив.
  2. $ mayarray и @myarray - это разные переменные
  3. Perl на самом деле не делает многомерных массивов

Все ссылки хранятся в скалярах, поэтому все ссылки хранятся в переменных, которые начинаются с $.

[ ... ] создает анонимную ссылку на массив, поэтому [ [1, 2, 3], [4, 5, 6], [7, 8, 9]] создает анонимную ссылку на массив, содержащий 3 анонимные ссылки на массив, каждая из которых содержит 3 скаляра.

Это означает, что присвоение $ myarray присваивает ему ссылку на внешний анонимный массив.

Чтобы получить доступ к тому, на что указывает ссылка два, нужно разыменовать его. Вы можете сделать это, поместив символ для типа того, на что указывает ссылка, перед ссылкой, такой как @$myarray. Таким образом, $$myarray[0] является первым элементом анонимного массива, содержащегося в ссылке $myarray, или вы можете использовать косвенный синтаксис $myarray->[0].

В вашем примере $myarray->[0] содержит ссылку на массив [1,2,3] Так что на него можно ссылаться таким же образом, давая $myarray->[0]->[0] Это говорит о разыменовании $myarray и дает мне первый элемент, который является ссылкой на массив, затем разыщите это и дайте мне первый элемент этого.

Это ваш второй пример.

Perl позволяет отбрасывать -> между ] и [, а также } и { для анонимных хэшей как синтаксический сахар. Это дает $myarray->[0][0], который является вашим первым примером.

Ваш третий пример ищет первый элемент @myarray, который отличается от $myarray. если бы вы поместили use strict в начало вашего скрипта, Perl поймал бы эту ошибку для вас.

Хорошая идея поставить

use strict;
use warnings;

Как первые две строки любого скрипта или модуля Perl, поскольку они будут отлавливать множество плохих и потенциально фатальных ошибок в вашей Программе. Если вы отлаживаете программу, то добавление use diagnostics в use strict дает больше подробных сообщений.

0 голосов
/ 18 января 2019

Первый и второй примеры функционально эквивалентны. Один - просто синтаксический сахар для другого.

Третий семантически отличается. Принимая во внимание, что допустимо пропускать операторы -> между индексами, недопустимо делать это между идентификаторами или вызовами и индексами подпрограмм, если переменная (или подпрограмма) содержит (или возвращает) ссылку, потому что Perl будет обрабатывать их как не ссылки в этом случае.

Не существует ситуации, когда $array->[1][2] мог бы означать что-либо, кроме $array->[1]->[2], но если бы было допустимо опустить стрелку между идентификатором и первым индексом, было бы неоднозначно, смотрела ли структура, индексируемая в как [1,...] или (1,...), это разные вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...