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 уроков всего.

Что такое выведение экземпляров?

Выведение экземпляров класса типов автоматически создаёт экземпляры на основе структуры типа, поэтому Вам не приходится вручную писать шаблонный код для каждого класса вариантов. Компилятор строит экземпляр из полей типа.

Проблема шаблонного кода

Без выведения для каждого нового класса вариантов нужен экземпляр, созданный вручную. Если требуется Show для двадцати классов вариантов, это двадцать почти одинаковых определений. Выведение устраняет такое повторение.

Сначала ручная композиция

До автоматического выведения важно отметить, что экземпляры можно вручную составлять из экземпляров полей. Именно этот принцип автоматизирует выведение.

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

case class User(name: String, age: Int)

object Main {
  implicit val strShow: Show[String] = s => s
  implicit val intShow: Show[Int] = _.toString

  implicit val userShow: Show[User] = (u: User) =>
    s"User(${strShow.show(u.name)}, ${intShow.show(u.age)})"

  def main(args: Array[String]): Unit = {
    println(userShow.show(User("Ann", 30)))
  }
}

Индуктивные экземпляры

Выведение работает индуктивно: сначала определяются экземпляры для примитивных типов, затем они объединяются для произведений (классов вариантов) и сумм (запечатанных трейтов). Производный экземпляр строится из своих частей.

Ключевое слово derives в Scala 3

Scala 3 поддерживает конструкцию derives. Класс типов с методом derived можно присоединить к типу с помощью одного ключевого слова. (Концептуальный фрагмент; требуется класс типов, поддерживающий выведение.)

enum Color derives CanEqual:
  case Red, Green, Blue

@main def run(): Unit =
  println(Color.Red == Color.Red)

Выведение на основе Mirror

Выведение в Scala 3 использует scala.deriving.Mirror, который во время компиляции предоставляет структуру типа (типы и имена полей). Метод derived сворачивает экземпляры элементов зеркала, чтобы построить целое.

Полуавтоматическое выведение

Библиотеки вроде Cats предлагают полуавтоматическое выведение: для каждого типа Вы явно включаете его одной строкой, например deriveShow. Это позволяет сохранять предсказуемое время компиляции и избавляться от шаблонного кода.

Автоматическое и полуавтоматическое выведение

Два подхода:

  • Автоматический: экземпляры появляются везде, где нужны, благодаря неявному импорту; это удобно, но может замедлить компиляцию.
  • Полуавтоматический: для каждого типа Вы явно пишете один вызов выведения; это обеспечивает больший контроль и более быструю сборку.

Выведение для запечатанных признаков

Для запечатанной иерархии (суммарного типа) выведенный экземпляр выбирает действие в зависимости от того, какому подтипу принадлежит значение. Здесь ручная версия показывает идею, которую автоматизирует выведение.

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

sealed trait Shape
case class Circle(r: Int) extends Shape
case class Square(s: Int) extends Shape

object Main {
  implicit val shapeShow: Show[Shape] = {
    case Circle(r) => s"Circle($r)"
    case Square(s) => s"Square($s)"
  }

  def main(args: Array[String]): Unit = {
    println(shapeShow.show(Circle(5)))
    println(shapeShow.show(Square(3)))
  }
}

Когда использовать выведение

Используйте выведение, когда:

  • У Вас много типов данных, которым нужен один и тот же класс типов (кодеки JSON, Show, Eq).
  • Экземпляр можно механически получить из структуры.

Пишите экземпляры вручную, если поведение нестандартное или критично с точки зрения производительности.

Пример обобщённого равенства

Равенство — классический пример выводимого класса типов. Стандартный оператор == для классов вариантов сам по себе является разновидностью структурного равенства, которое компилятор генерирует за Вас.

case class Coord(x: Int, y: Int)

object Main {
  def main(args: Array[String]): Unit = {
    println(Coord(1, 2) == Coord(1, 2))
    println(Coord(1, 2) == Coord(3, 4))
  }
}

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

Проверьте, насколько хорошо Вы поняли выведение.

Итоги

Вы изучили выведение классов типов:

  • Экземпляры строятся индуктивно из экземпляров полей и вариантов.
  • Scala 3 использует Mirror и ключевое слово derives.
  • Выбирайте автоматическое выведение для удобства, а полуавтоматическое — для контроля.
  • Используйте его, чтобы устранить шаблонный код во множестве типов данных.

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

Урок «Выведение классов типов» бесплатный?

Да — полный текст урока «Выведение классов типов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 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. Определение экземпляров
  3. Распространённые классы типов
  4. Выведение классов типов
← Назад к Scala for Backend Engineering & Functional Programming