Каковы последствия "$ scalar = @array [n]"? - PullRequest
4 голосов
/ 14 марта 2011
use warnings;
my @array = (0, 1);
my $scalar1 = $array[0];
my $scalar2 = @array[0];
if($scalar1 == $scalar2) {
    print "scalars are equal\n";
}

Вот вывод, когда я запускаю /usr/bin/perl5.10.1 test.pl:

Scalar value @array[0] better written as $array[0] at test.pl line 4.
scalars are equal

Я обеспокоен этим предупреждением.

Ответы [ 3 ]

11 голосов
/ 14 марта 2011

Вы можете просмотреть все предупреждающие сообщения в perldoc perldiag , что объясняет последствия:

(W синтаксис) Вы использовали срез массива (обозначенный @), чтобы выбрать один элемент массива. В общем-то лучше попросить скалярное значение (указано $). Разница в том, что $ foo [& bar] всегда ведет себя как скаляр, как при назначении ему и при оценке своего аргумента, в то время как @foo [& bar] ведет себя как список, когда Вы назначаете на него, и предоставляет список контекст для его индекса, который может сделать странные вещи, если вы ожидаете только один индекс.

С другой стороны, если вы действительно надеетесь обработать массив элемент в виде списка, нужно посмотреть в том, как работают ссылки, потому что Perl не будет магически конвертировать между скаляры и списки для вас. Увидеть perlref.

Аналогично, вы можете использовать диагностику; , чтобы получить подробное объяснение предупреждающего сообщения.

Третий способ - использовать утилиту splain .

5 голосов
/ 14 марта 2011

Нет никаких последствий для этого использования. Я думаю, что цель состоит в том, чтобы помочь вам избежать последствий, когда предупреждение не может быть выдано.

Срезы на LHS "=" причиной = "являются оператором назначения списка.

$ perl -E'sub f { return 4; } my $x = $a[1] = f(); say $x'
4

$ perl -E'sub f { return 4; } my $x = @a[1] = f(); say $x'
1

Срезы оценивают индекс в контексте списка.

$ perl -E'sub f { my @i = 3; @i } @a=qw( a b c d e f ); say @a[f()]'
d

$ perl -E'sub f { my @i = 3; @i } @a=qw( a b c d e f ); say $a[f()]'
b
5 голосов
/ 14 марта 2011

Можно взять фрагмент массива из одного элемента:

@fruits[1]; # array slice of one element

, но обычно это означает, что вы допустили ошибку, и Perl предупредит вас , что вына самом деле следует писать это:

$fruits[1];
...