Курс по 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 контекст — контекстът на оператор, чиято стойност се изхвърля, като ред, който съществува само заради страничния си ефект. Когато стойност попадне в sink контекст без нищо полезно за правене, Raku може да предупреди за „useless use”, което е полезна подсказка, че сте забравили да използвате резултата.

Сигилът, който избирате ($ срещу @), всъщност е избор на контекст, а контекстуализаторите $( ) и @( ) ви позволяват да го промените, когато е необходимо.

Практика

Направете 1 тест върху съдържанието на тази тема.

Навигация в курса

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


💪 Или преминете направо към упражненията в този раздел.