Курс языка программирования Raku / Продвинутый уровень / Операторы / Метаоператоры
Перекрёстные, гипер- и отрицающие
Кроме свёртки и zip в Raku есть ещё несколько метаоператоров. Три из них стоит знать уже сейчас.
Перекрёстный — X
Перекрёстный метаоператор X сочетает
каждый элемент одного списка с каждым
элементом другого — это декартово произведение:
say <a b> X <1 2>; # ((a 1) (a 2) (b 1) (b 2))Как и zip, он может обернуть оператор, чтобы подействовать на каждую
пару. X~ соединяет каждую пару в строку, а X*
перемножает:
say <a b> X~ <1 2>; # (a1 a2 b1 b2)
say (1, 2, 3) X* (10, 100); # (10 100 20 200 30 300)Если zip проходит по двум спискам в ногу, то перекрёстный оператор сочетает их всеми возможными способами.
Гипероператор — »…«
Гипероператор применяет оператор к каждому элементу
списка. Оператор заключается в угловые стрелки »…« (или в
ASCII-запись >>…<<). С двумя списками он
работает поэлементно, как zip; а если с одной стороны стоит одно
значение, оно растягивается на весь список:
say (1, 2, 3) »+» (10, 20, 30); # (11 22 33)
say (1, 2, 3) »*» 2; # (2 4 6)Стрелки не обязаны смотреть в одну сторону, и их направление решает,
что произойдёт, если длины списков не совпадают: остриё, направленное
на список, разрешает повторять этот список, подгоняя
его под другой. В ASCII-записи
<</>> возможны четыре
сочетания:
>>op<<— ни одна сторона не растягивается; списки должны быть одной длины, иначе будет ошибка;>>op>>— правый список повторяется, подгоняясь под левый;<<op<<— левый список повторяется, подгоняясь под правый;<<op>>— более короткий список повторяется, подгоняясь под более длинный.
say (1, 2, 3, 4) <<+>> (10, 20); # (11 22 13 24) — 10, 20 повторяется как 10, 20, 10, 20Есть и унарная форма, которая вызывает метод у каждого элемента.
>>.uc переводит каждую строку в верхний регистр:
say <raku perl>>>.uc; # (RAKU PERL)Гипероперации к тому же означают, что работа может
выполняться параллельно — со связанным методом .hyper вы
встретитесь позже, в разделе о
конкурентном программировании.
Отрицающий — !
Если поставить ! перед оператором сравнения, его
результат меняется на противоположный. Привычный != (не
равно) — это ровно тот же метаоператор, применённый к ==, и
точно так же он работает с другими логическими операторами, например
eq и %%:
say 3 != 4; # True
say 'a' !eq 'b'; # True — не равны как строки
say 5 !%% 2; # True — 5 не делится на 2Коротко говоря, $a !op $b — это просто более аккуратная
запись для !($a op $b).
И так задумано. В отличие от нарочито минималистичного языка вроде
эсперанто, который стремится дать один правильный способ выразить каждую
мысль, Raku охотно предлагает несколько — поэтому отрицающий
!eq соседствует с отдельным оператором ne, и
означают они ровно одно и то же:
say 'a' ne 'b'; # True — та же проверка, что и 'a' !eq 'b'Практика
Пройдите 1 тест по содержанию этой темы.
Навигация по курсу
← Метаоператоры zip | Тест — Гипер- и перекрёстные операторы →
💪 Или перейдите сразу к упражнениям этого
раздела.