В чем разница между контекстами scalar и list в Perl?

StackOverflow https://stackoverflow.com/questions/376921

  •  22-08-2019
  •  | 
  •  

Вопрос

В чем разница между контекстами scalar и list в Perl и имеет ли это какие-либо параллели в других языках, таких как Java или Javascript?

Это было полезно?

Решение

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

Например:

my(@array) = (1, 2, 4, 8, 16);
my($first) = @array;
my(@copy1) = @array;
my @copy2  = @array;
my $count  = @array;

print "array: @array\n";
print "first: $first\n";
print "copy1: @copy1\n";
print "copy2: @copy2\n";
print "count: $count\n";

Выходной сигнал:

array: 1 2 4 8 16
first: 1
copy1: 1 2 4 8 16
copy2: 1 2 4 8 16
count: 5

Сейчас:

  • $first содержит 1 (первый элемент массива), поскольку круглые скобки в my($first) предоставьте контекст массива, но в нем есть место только для одного значения $first.
  • и то, и другое @copy1 и @copy2 содержать копию @array,
  • и $count содержит 5, потому что это скалярный контекст, и @array вычисляет количество элементов в массиве в скалярном контексте.

Можно было бы также построить более сложные примеры (результаты являются упражнением для читателя).:

my($item1, $item2, @rest) = @array;
my(@copy3, @copy4) = @array, @array;

В других известных мне языках нет прямой параллели со списком и скалярным контекстом.

Другие советы

Скалярный контекст - это то, что вы получаете, когда ищете одно значение.Контекст списка - это то, что вы получаете, когда ищете несколько значений.Одно из наиболее распространенных мест, где можно увидеть различие, - это при работе с массивами:

@x = @array;  # copy an array
$x = @array;  # get the number of elements in an array

Другие операторы и функции также зависят от контекста:

$x   = 'abc' =~ /(\w+)/;  # $x = 1
($x) = 'abc' =~ /(\w+)/;  # $x = 'abc'
@x   = localtime();       # (seconds, minutes, hours...)
$x   = localtime();       # 'Thu Dec 18 10:02:17 2008'

То, как оператор (или функция) ведет себя в данном контексте, зависит от оператора.Не существует общих правил относительно того, как должны вести себя вещи.

Вы можете сделать свои собственные подпрограммы контекстно-зависимыми, используя wantarray функция для определения контекста вызова.Вы можете принудительно вычислить выражение в скалярном контексте, используя scalar ключевое слово.

В дополнение к контекстам scalar и list вы также увидите контексты "void" (ожидаемое возвращаемое значение отсутствует) и "boolean" (ожидаемое значение true / false), упомянутые в документации.

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

Я думаю, что лучший способ понять контекст - это узнать о wantarray.Итак, представьте, что = - это подпрограмма , которая реализует wantarray:

sub = {
  return if ( ! defined wantarray ); # void: just return (doesn't make sense for =)
  return @_ if ( wantarray ); # list: return the array
  return $#_ + 1; # scalar: return the count of the @_
}

Примеры в этот пост работайте так, как если бы вышеупомянутая подпрограмма вызывалась путем передачи правой части в качестве параметра.

Что касается параллелей в других языках, да, я по-прежнему утверждаю, что практически каждый язык поддерживает что-то подобное.Полиморфизм одинаков во всех языках OO.Другой пример: Java преобразует объекты в строку в определенных контекстах.И каждый нетипизированный скриптовый язык, который я использовал, имеет схожие концепции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top