Курс Raku / Розширені / Контейнери / Контексти 🆕

Елементний та списковий контекст

Ще два контексти вирішують, чи розглядати щось як список із кількох значень, чи як один елемент. Саме в цьому полягає різниця між сигілами @ та $.

У списковому контексті масив розгортається у свої елементи. Цикл for ставить свій аргумент у списковий контекст, тож проходить по кожному елементу:

my @a = 1, 2, 3;

my $count = 0;
$count++ for @a;
say $count; # 3

У штучному контексті той самий масив розглядається як одне-єдине значення. Контекстуалізатор $( … ) задає штучний контекст, тож цикл тепер бачить лише одну річ і виконується один раз:

my @a = 1, 2, 3;

my $count = 0;
$count++ for $(@a);
say $count; # 1

Саме тому присвоєння масиву скаляру пакує його як один елемент, а не копіює його елементи: my $x = @a ставить @a у штучний контекст. Зауважте, що цим одним елементом може бути інший контейнер із багатьма елементами всередині:

my @a = 1, 2, 3;

my $var = @a;
say $var;      # [1 2 3]
say $var.WHAT; # (Array)

Змінна $var тепер містить один (адже це скалярний контейнер) об’єкт, яким є Array. Легко довести це, розглядаючи $x як своєрідне посилання на масив (як його назвали б в інших мовах):

say $var[1]; # 2

Парний контекстуалізатор @( … ) робить протилежне — задає списковий контекст.

Є ще контекст стоку (sink context) — контекст оператора, значення якого відкидається, як-от рядок, що існує лише заради побічного ефекту. Коли значення потрапляє в контекст стоку, не маючи чого корисного робити, Raku може попередити про «useless use», і це зручний натяк, що ви забули скористатися результатом.

Сигіл, який ви обираєте ($ проти @), насправді є вибором контексту, а контекстуалізатори $( ) та @( ) дозволяють перевизначити його там, де це потрібно.

Практика

Виконайте 1 тест за змістом цієї теми.

Навігація курсом

Тест — Контексти   |   Тест — Елементний контекст


💪 Або перейдіть одразу до вправ цього розділу.