0Pricing
Scala for Backend Engineering & Functional Programming · Урок

Методы-расширения

Добавляйте методы типам

«Методы-расширения» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Добавление методов к существующим типам

Методы расширения позволяют добавлять новые методы к типу, которым Вы не владеете, например к Int или String, не изменяя его исходный код. В Scala 3 для этого предусмотрен удобный синтаксис.

object Main:
  extension (x: Int)
    def squared: Int = x * x
  def main(args: Array[String]): Unit =
    println(5.squared)

Синтаксис расширений

Запишите extension (param: Type), а затем одно или несколько определений методов. Внутри каждого метода параметр обозначает значение-получатель.

object Main:
  extension (s: String)
    def shout: String = s.toUpperCase + "!"
  def main(args: Array[String]): Unit =
    println("hello".shout)

Несколько методов в одном блоке

Один оператор extension может определить несколько методов, которые работают с одним и тем же типом-получателем.

object Main:
  extension (x: Int)
    def squared: Int = x * x
    def cubed: Int = x * x * x
    def isEven: Boolean = x % 2 == 0
  def main(args: Array[String]): Unit =
    println(4.squared)
    println(3.cubed)
    println(6.isEven)

Методы расширения с параметрами

Методы расширения могут принимать собственные параметры в дополнение к параметру-получателю.

object Main:
  extension (x: Int)
    def times(s: String): String = s * x
  def main(args: Array[String]): Unit =
    println(3.times("ab"))

Обобщённые методы расширения

Расширения могут быть обобщёнными и добавлять методы ко всему семейству типов, например к List[A].

object Main:
  extension [A](xs: List[A])
    def second: A = xs(1)
  def main(args: Array[String]): Unit =
    println(List(10, 20, 30).second)
    println(List("a", "b").second)

Почему расширения лучше неявных преобразований

Методы расширения безопаснее реализуют прежнюю идею «улучшения библиотеки»: они добавляют только названные методы и не создают риска незаметных преобразований типов в других местах.

object Main:
  extension (d: Double)
    def percentOf(total: Double): Double = d / total * 100
  def main(args: Array[String]): Unit =
    println(25.0.percentOf(200.0))

Расширения и классы типов

Методы расширения прекрасно сочетаются с классами типов: определите поведение с помощью экземпляра given, а затем предоставьте его как метод с помощью using.

trait Show[A]:
  def show(a: A): String

object Main:
  given Show[Int] with
    def show(a: Int): String = s"<$a>"

  extension [A](a: A)
    def display(using s: Show[A]): String = s.show(a)

  def main(args: Array[String]): Unit =
    println(42.display)

Определение операторов

Поскольку операторы — это всего лишь методы, расширения также могут добавлять символьные операторы к существующим типам.

object Main:
  extension (x: Int)
    def **(exp: Int): Int = math.pow(x, exp).toInt
  def main(args: Array[String]): Unit =
    println(2 ** 10)

Область действия и импорты

Методы расширения доступны только там, где они находятся в области действия. Определите их в объекте и импортируйте этот объект для использования, контролируя тем самым область их применения.

object StringOps:
  extension (s: String)
    def reversedWords: String = s.split(" ").reverse.mkString(" ")

object Main:
  import StringOps._
  def main(args: Array[String]): Unit =
    println("hello there world".reversedWords)

Цепочки методов расширения

Методы расширения возвращают обычные значения, поэтому их можно объединять со встроенными методами, создавая последовательные цепочки обработки.

object Main:
  extension (s: String)
    def emphasize: String = s"*$s*"
  def main(args: Array[String]): Unit =
    println("scala".toUpperCase.emphasize)

Практический вспомогательный метод

Методы расширения идеально подходят для небольших предметно-ориентированных вспомогательных методов, благодаря которым вызывающий код читается естественно.

object Main:
  extension (n: Int)
    def isPrime: Boolean =
      n > 1 && (2 until n).forall(d => n % d != 0)
  def main(args: Array[String]): Unit =
    println((2 to 12).filter(_.isPrime).toList)

Быстрая проверка

В чём главное преимущество методов расширения Scala 3 перед неявными преобразованиями при добавлении методов?

Итоги

Вы изучили методы расширения:

  • extension (x: Type) def ... добавляет методы к существующим типам
  • Один блок может определять несколько методов, включая операторы
  • Они могут быть обобщёнными и принимать параметры
  • Они естественно сочетаются с классами типов через using
  • Они безопаснее неявных преобразований, но должны быть импортированы в область действия

Часто задаваемые вопросы

Урок «Методы-расширения» бесплатный?

Да — полный текст урока «Методы-расширения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Чему я научусь в уроке «Методы-расширения»?

Добавляйте методы типам Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?

Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Методы-расширения»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?

Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Неявные параметры
  2. Scala 3 given/using
  3. Неявные преобразования
  4. Методы-расширения
← Назад к Scala for Backend Engineering & Functional Programming