Объект Экстрактор
Info: JavaScript is currently disabled, code tabs will still work, but preferences will not be remembered.
Объект Экстрактор (объект распаковщик или extractor object) - это объект с методом unapply. В то время как метод apply обычно действует как конструктор, который принимает аргументы и создает объект, метод unapply действует обратным образом, он принимает объект и пытается извлечь и вернуть аргументы из которых он (возможно) был создан. Чаще всего этот метод используется в функциях сопоставления с примером и в частично определенных функциях.
import scala.util.Random
object CustomerID {
 def apply(name: String) = s"$name--${Random.nextLong()}"
 def unapply(customerID: String): Option[String] = {
 val stringArray: Array[String] = customerID.split("--")
 if (stringArray.tail.nonEmpty) Some(stringArray.head) else None
 }
}
val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908
customer1ID match {
 case CustomerID(name) => println(name) // выведет Sukyoung
 case _ => println("Could not extract a CustomerID")
}
import scala.util.Random
object CustomerID:
 def apply(name: String) = s"$name--${Random.nextLong()}"
 def unapply(customerID: String): Option[String] =
 val stringArray: Array[String] = customerID.split("--")
 if stringArray.tail.nonEmpty then Some(stringArray.head) else None
val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908
customer1ID match
 case CustomerID(name) => println(name) // выведет Sukyoung
 case _ => println("Could not extract a CustomerID")
Метод apply создает CustomerID из строки name. unapply делает обратное, чтобы вернуть name обратно. Когда мы вызываем CustomerID("Sukyoung"), это сокращенный синтаксис вызова CustomerID.apply("Sukyoung"). Когда мы вызываем case CustomerID(name) => println(name), мы на самом деле вызываем метод unapply.
При объявлении нового значения можно использовать пример, в котором значение для инициализации переменной получается через извлечение, используя метод unapply.
val customer2ID = CustomerID("Nico")
val CustomerID(name) = customer2ID
println(name) // выведет Nico
Что эквивалентно val name = CustomerID.unapply(customer2ID).get.
val CustomerID(name2) = "--asdfasdfasdf"
Если совпадений нет, то бросается scala.MatchError:
val CustomerID(name3) = "-asdfasdfasdf"
Возвращаемый тип unapply выбирается следующим образом:
- Если это всего лишь тест, возвращается 
Boolean. Напримерcase even(). - Если в результате найдено одно значение типа 
T, то возвращаетсяOption[T]. - Если вы хотите получить несколько значений 
T1,..., Tn, то ответ необходимо группировать в дополнительный кортежOption[(T1,..., Tn)]. 
Иногда количество извлекаемых значений не является фиксированным. Если в зависимости от входа мы хотим вернуть произвольное количество значений, то для этого случая мы можем определить экстрактор методом unapplySeq, который возвращает Option[Seq[T]]. Характерным примером такого подхода является разложение List с помощью case List(x, y, z) => и разложение String с помощью регулярного выражения Regex, такого как case r(name, remainingFields @ _*) =>.
Contributors to this page:
Contents
- Введение
 - Основы
 - Единобразие типов
 - Классы
 - Значения Параметров По умолчанию
 - Именованные Аргументы
 - Трейты
 - Кортежи
 - Композиция классов с трейтами
 - Функции Высшего Порядка
 - Вложенные Методы
 - Множественные списки параметров (Каррирование)
 - Классы Образцы
 - Сопоставление с примером
 - Объекты Одиночки
 - Регулярные Выражения
 - Объект Экстрактор
 - Сложные for-выражения
 - Обобщенные Классы
 - Вариантность
 - Верхнее Ограничение Типа
 - Нижнее Ограничение Типа
 - Внутренние классы
 - Члены Абстрактного Типа
 - Составные Типы
 - Самоописываемые типы
 - Контекстные параметры, также известные, как неявные параметры
 - Неявные Преобразования
 - Полиморфные методы
 - Выведение Типа
 - Операторы
 - Вызов по имени
 - Аннотации
 - Пакеты и Импорт
 - Объекты Пакета