Курс языка программирования Raku / Продвинутый уровень / Подпрограммы

Звёздочка Whatever

Вы, возможно, уже встречали * в выражениях вроде * * 2 или * %% 2 при вызове map и grep. Эта * — так называемая звёздочка Whatever, и выражение вокруг неё на лету создаёт небольшую функцию с одним аргументом. В этом разделе объясняется, что она на самом деле собой представляет, как соотносится с блоком и где голая звёздочка означает просто «что угодно».

Звёздочка создаёт функцию

Когда * появляется в выражении, Raku превращает всё выражение в функцию — WhateverCode, — в которой звёздочка обозначает аргумент:

my $double = * * 2;

say $double.^name; # WhateverCode
say $double(21);   # 42

* * 2 — это функция, которая умножает свой единственный аргумент на два. Именно поэтому работает (1..5).map(* * 2): map получает именно такую функцию с одним аргументом.

Whatever и блок

Выражение с Whatever — это краткая запись функции, которую можно также записать в виде блока. Следующие три записи эквивалентны:

* * 2
{ $_ * 2 }
-> $x { $x * 2 }

В форме с Whatever параметр не указывается; в форме блока используется топик-переменная $_; в стрелочной форме явно задаётся $x. Последний вариант, -> $x { ... }, — это самостоятельная маленькая функция, с которой вы подробнее познакомитесь в разделе Анонимные подпрограммы; здесь достаточно воспринимать его как третий способ записать ту же функцию с одним аргументом. Для простого выражения звёздочка — самая компактная форма, поэтому она так часто используется с map, grep и sort:

say (1..5).map(* * 2);            # (2 4 6 8 10)
say (1..5).map({ $_ * 2 });       # (2 4 6 8 10)
say (1..5).map(-> $x { $x * 2 }); # (2 4 6 8 10)

Используйте блок, когда логика требует нескольких выражений или когда именованный параметр делает код понятнее. Используйте звёздочку, когда короткое выражение говорит само за себя.

Несколько звёздочек

Каждая * в выражении — это отдельный аргумент, по порядку. Таким образом, две звёздочки создают функцию с двумя аргументами:

my $add = * + *;

say $add(3, 4); # 7

Здесь * + * — это функция с двумя аргументами, которая складывает их — например, промежуточную сумму и следующий элемент.

Голая звёздочка Whatever

Сама по себе * означает «что угодно» — сколько есть или без ограничения. Два повседневных примера:

my @a = 10, 20, 30;
say @a[*-1];        # 30  — * — это длина массива, поэтому *-1 — последний индекс

say (1..*).head(3); # (1 2 3)  — 1..* — это диапазон без верхней границы

В @a[*-1] звёздочка обозначает количество элементов, а в 1..* — «без верхней границы». Создаёт ли она функцию или означает «что угодно» — звёздочка остаётся одним из самых полезных сокращений в Raku.

Практика

Пройдите 1 тест по содержанию этой темы.

Упражнения

В этом разделе 3 упражнения. Прежде чем приступать к практике, изучите все темы раздела.

  1. Whatever с map
  2. Whatever с двумя аргументами
  3. Открытый диапазон

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

Тест — Поглощающие параметры   |   Whatever с map