Объект Экстрактор (объект распаковщик или 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-выражения
- Обобщенные Классы
- Вариантность
- Верхнее Ограничение Типа
- Нижнее Ограничение Типа
- Внутренние классы
- Члены Абстрактного Типа
- Составные Типы
- Самоописываемые типы
- Контекстные параметры, также известные, как неявные параметры
- Неявные Преобразования
- Полиморфные методы
- Выведение Типа
- Операторы
- Вызов по имени
- Аннотации
- Пакеты и Импорт
- Объекты Пакета