У меня есть последовательность элементов, в частности байтов, которые я хотел бы совместить с чем-то более высоким уровнем, например. 16-разрядные целые числа. Наивный подход будет выглядеть следующим образом:, соответствующий нескольким элементам из последовательности элементов
val stream: Seq[Byte] = ???
def short(b1: Byte, b0: Byte): Short = ???
stream match {
case Seq(a1, a0, b1, b0, _*) => (short(a1, a0), short(b1, b0))
// ...
}
Что мне удалось сделать что-то вроде этого, используя object short_::
с unapply
способом:
stream match {
case a short_:: b short_:: _ => (a, b)
// ...
}
Однако, я не могу сказать, что я люблю синтаксис здесь, потому что он не очень похож на регулярное сопоставление шаблонов. Я бы счастливее, чтобы написать что-то вроде этого:
stream match {
case Short(a) :: Short(b) :: _ => (a, b)
// ...
}
Конечно, с помощью идентификаторов Short
и ::
, вероятно, трудно/плохая идея, но я думаю, что он получает точку в поперечнике для целей данного вопроса.
Возможно ли написать собственный код соответствия шаблону, который создает синтаксис, подобный этому? Я ограничиваю себя содержимым с фиксированной шириной потока здесь (хотя и не одной ширины: например, Short и Int должны быть возможны), но мне нужно иметь возможность сопоставлять оставшуюся часть потока, например :: tail
или Seq(..., tail @ _*)
.
Ну, мне кажется, что ваш первый подход не наивен. Напротив, это вполне может быть одним из естественных способов достичь этого. –