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

Сопоставление типов и значений

Шаблоны типов

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

Шаблоны типов

Помимо сопоставления с конкретными значениями, match может выбирать ветвь по типу значения. Это называется шаблоном типа.

Запись case x: Type => означает, что ветвь выполнится, если значение имеет этот тип, и привязывает его к x.

Сопоставление по типу

Если значение имеет общий тип, например Any, с помощью шаблона типа можно определить его конкретный тип.

Каждый вариант case x: T проверяет тип во время выполнения.

object Main {
  def describe(x: Any): String = x match {
    case i: Int    => "an Int"
    case s: String => "a String"
    case _         => "something else"
  }
  def main(args: Array[String]): Unit = {
    println(describe(5))
    println(describe("hi"))
    println(describe(3.14))
  }
}

Использование привязанного значения

Привязанное имя имеет сопоставленный тип, поэтому в этой ветви можно безопасно вызывать его методы.

Приведение типов не требуется: внутри варианта компилятор знает тип.

object Main {
  def shout(x: Any): String = x match {
    case s: String => s.toUpperCase
    case i: Int    => (i * 2).toString
    case _         => "?"
  }
  def main(args: Array[String]): Unit = {
    println(shout("hello"))
    println(shout(21))
  }
}

Тип и значение вместе

В одном match можно сочетать шаблоны значений и типов. Шаблоны значений обычно более специфичны, поэтому размещайте их первыми.

object Main {
  def check(x: Any): String = x match {
    case 0       => "zero int"
    case i: Int  => s"nonzero int $i"
    case _       => "not an int"
  }
  def main(args: Array[String]): Unit = {
    println(check(0))
    println(check(7))
    println(check("x"))
  }
}

Сопоставление Double и Boolean

Шаблоны типов работают с любыми типами, включая Double, Boolean и Char.

object Main {
  def kind(x: Any): String = x match {
    case d: Double  => s"double $d"
    case b: Boolean => s"bool $b"
    case _          => "other"
  }
  def main(args: Array[String]): Unit = {
    println(kind(2.5))
    println(kind(true))
  }
}

Сопоставление коллекций по типу

Можно также сопоставлять типы контейнеров, например List. Здесь мы отличаем список от других значений.

object Main {
  def info(x: Any): String = x match {
    case l: List[_] => s"a list of size ${l.size}"
    case _          => "not a list"
  }
  def main(args: Array[String]): Unit = {
    println(info(List(1, 2, 3)))
    println(info("nope"))
  }
}

Распространённое применение: обработка Any

Шаблоны типов особенно полезны, когда функция получает значение типа Any и должна по-разному обрабатывать значения разных типов, например при ведении журнала или сериализации.

object Main {
  def render(x: Any): String = x match {
    case i: Int    => s"int=$i"
    case d: Double => s"dbl=$d"
    case s: String => s"str=$s"
    case _         => "unknown"
  }
  def main(args: Array[String]): Unit = {
    List(1, 2.0, "three").foreach(v => println(render(v)))
  }
}

Порядок по-прежнему имеет значение

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

Всегда располагайте варианты от самых специфичных к самым общим.

object Main {
  def label(x: Any): String = x match {
    case s: String => "string first"
    case _: Any    => "anything"
  }
  def main(args: Array[String]): Unit = {
    println(label("hi"))
    println(label(99))
  }
}

Ограничение, связанное со стиранием типов

Во время выполнения параметры обобщённых типов стираются. Поэтому List[Int] и List[String] выглядят одинаково. Сопоставление с List[Int] проверяет только то, что значение является List.

Используйте List[_], чтобы явно указать это и избежать предупреждений.

Зачем нужны шаблоны типов?

Шаблоны типов позволяют:

  • Безопасно уточнять общий тип без приведения
  • Корректно обрабатывать значения разных типов
  • Сочетать шаблоны типов со шаблонами значений и условиями

Это шаг к сопоставлению с классами case и алгебраическими типами данных.

Собираем всё вместе

Сочетайте шаблоны значений и типов, чтобы классифицировать смешанные входные данные.

object Main {
  def classify(x: Any): String = x match {
    case 0          => "zero"
    case i: Int     => "int"
    case s: String  => "text of length " + s.length
    case _          => "other"
  }
  def main(args: Array[String]): Unit = {
    println(classify(0))
    println(classify(5))
    println(classify("hey"))
  }
}

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

Проверьте свои знания о шаблонах типов.

Итоги

Вы научились сопоставлять значения по типам:

  • case x: Type сопоставляет по типу во время выполнения и привязывает значение к x
  • Привязанное значение имеет сопоставленный тип, поэтому приведение не требуется
  • Сочетайте шаблоны значений и типов, начиная с самых специфичных
  • Параметры обобщённых типов стираются, поэтому используйте List[_]

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

Урок «Сопоставление типов и значений» бесплатный?

Да — полный текст урока «Сопоставление типов и значений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 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 структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Сопоставление типов и значений»?

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

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

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

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

  1. Выражения match
  2. Сопоставление типов и значений
  3. Защитные условия и привязка
  4. Деструктуризация
← Назад к Scala for Backend Engineering & Functional Programming