Extension-методы в Scala 3
Один из вариантов создания кортежа из 2-х элементов — применение a -> b, что является альтернативой всем привычного (a, b). В Scala 2-й версии это имплементировано посредством неявного преобразования из типа переменной a в ArrowAssoc, где определен метод ->:
На что тут важно обратить внимание? На то, что юникодовская стрелочка → помечается как deprecated.
Все это является довольно типичным для Scala 2: если есть желание, чтобы метод казался частью типа, надо сделать неявное преобразование к типу-обертке, предоставляющему этот метод.
Иными словами, в Scala 2 для этого задействуется универсальный механизм имплиситов, что позволяет достичь конкретной цели: появления extension-метода. Кстати, именно таким образом в других языках программирования (в том же C#) называют способ добавления к типу метода, объявленного вне этого типа.
Но перейдем к Scala 3 -- здесь extension-методы становятся сущностями 1-го класса. Давайте посмотрим, как мы можем переписать ArrowAssoc, применяя ~> в качестве имени метода:
Поначалу у нас идет ключевое слово extension, далее -- типы-параметры (в нашем случае — это [A, B]). Таким образом, A представляет собой тип, который мы расширяем, причем значение a дает возможность сослаться на экземпляр этого типа, для которого и был вызван наш extension-метод (аналог this). Также учтите, что в примере применяется бесскобочный синтаксис. Ну и после ключевого слова extension вы можете указать сколько хотите методов.
Отдельного упоминания в Scala 3 заслуживает аннотация @targetName. Посредством ее вы сможете определить буквенно-цифровое имя для методов, которые выполняют в Scala роль операторов. Причем данное имя нельзя будет применять из Scala-кода (нельзя будет написать a.arrow2(b)), зато можно будет использовать из Java-кода, чтобы вызвать соответствующий метод. Собственно говоря, применение аннотации @targetName рекомендуют сегодня для всех "операторных" методов.
По материалам статьи "Scala 3: Contextual Abstractions".