Эта страница документа относится к 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
Contributors to this page:
Contents
- Введение
- Возможности Scala
- Почему Scala 3?
- Почувствуй Scala
- Пример 'Hello, World!'
- REPL
- Переменные и типы данных
- Структуры управления
- Моделирование данных
- Методы
- Функции первого класса
- Одноэлементные объекты
- Коллекции
- Контекстные абстракции
- Верхнеуровневые определения
- Обзор
- Первый взгляд на типы
- Интерполяция строк
- Структуры управления
- Моделирование предметной области
- Инструменты
- Моделирование ООП
- Моделирование ФП
- Методы
- Особенности методов
- Main методы в Scala 3
- Обзор
- Функции
- Анонимные функции
- Параметры функции
- Eta расширение
- Функции высшего порядка
- Собственный map
- Создание метода, возвращающего функцию
- Обзор
- Пакеты и импорт
- Коллекции в Scala
- Типы коллекций
- Методы в коллекциях
- Обзор
- Функциональное программирование
- Что такое функциональное программирование?
- Неизменяемые значения
- Чистые функции
- Функции — это значения
- Функциональная обработка ошибок
- Обзор
- Типы и система типов
- Определение типов
- Параметризованные типы
- Пересечение типов
- Объединение типов
- Алгебраические типы данных
- Вариантность
- Непрозрачные типы
- Структурные типы
- Зависимые типы функций
- Другие типы
- Контекстные абстракции
- Методы расширения
- Параметры контекста
- Контекстные границы
- Given импорты
- Классы типов
- Многостороннее равенство
- Неявное преобразование типов
- Обзор
- Параллелизм
- Scala утилиты
- Сборка и тестирование проектов Scala с помощью Sbt
- Рабочие листы
- Взаимодействие с Java