Сопоставление типов и значений
Шаблоны типов
«Сопоставление типов и значений» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Выражения match
- Сопоставление типов и значений
- Защитные условия и привязка
- Деструктуризация