Эта страница документа относится к Scala 3 и может охватывать новые концепции, недоступные в Scala 2. Если не указано явно, все примеры кода на этой странице предполагают, что вы используете Scala 3.
В Scala 2 аналогичного результата можно добиться с помощью неявных классов.
Методы расширения позволяют добавлять методы к типу после того, как он был определен, т.е. они позволяют добавлять новые методы в закрытые классы. Например, представьте, что кто-то создал класс Circle
:
case class Circle(x: Double, y: Double, radius: Double)
Теперь представим, что необходим метод circumference
, но нет возможности изменить исходный код Circle
. До того как концепция вывода терминов была введена в языки программирования, единственное, что можно было сделать, это написать метод в отдельном классе или объекте, подобном этому:
object CircleHelpers { def circumference(c: Circle): Double = c.radius * math.Pi * 2 }
object CircleHelpers: def circumference(c: Circle): Double = c.radius * math.Pi * 2
Затем этот метод можно было использовать следующим образом:
val aCircle = Circle(2, 3, 5) // без использования метода расширения CircleHelpers.circumference(aCircle)
Но методы расширения позволяют создать метод circumference
для работы с экземплярами Circle
:
extension (c: Circle) def circumference: Double = c.radius * math.Pi * 2
В этом коде:
Circle
— это тип, к которому будет добавлен метод расширенияcircumference
- Синтаксис
c: Circle
позволяет ссылаться на переменнуюc
в методах расширения
Затем в коде метод circumference
можно использовать так же, как если бы он был изначально определен в классе Circle
:
aCircle.circumference
Импорт методов расширения
Представим, что circumference
определен в пакете lib
- его можно импортировать с помощью
import lib.circumference aCircle.circumference
Если импорт отсутствует, то компилятор выводит подробное сообщение об ошибке, подсказывая возможный импорт, например так:
value circumference is not a member of Circle, but could be made available as an extension method. The following import might fix the problem: import lib.circumference
Обсуждение
Ключевое слово extension
объявляет о намерении определить один или несколько методов расширения для типа, заключенного в круглые скобки. Чтобы определить для типа несколько методов расширения, используется следующий синтаксис:
extension (c: Circle) def circumference: Double = c.radius * math.Pi * 2 def diameter: Double = c.radius * 2 def area: Double = math.Pi * c.radius * c.radius