Могут ли экстракторы быть настроены с параметрами в теле оператора case (или в другом месте, где будет использоваться экстрактор)? - PullRequest
14 голосов
/ 09 марта 2010

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

Это не реальный пример того, как я бы его использовал, скорее он будет использоваться в случае регулярного выражения или некоторого другого строкового шаблона, например конструкции, но, надеюсь, это объясняет, что я ищу: 1003 *

def someExtractorBuilder(arg:Boolean) = new {
  def unapply(s:String):Option[String] = if(arg) Some(s) else None
}

//I would like to be able to use something like this 
val {someExtractorBuilder(true)}(result) = "test"
"test" match {case {someExtractorBuilder(true)}(result) => result }

//instead I would have to do this:
val customExtractor = someExtractorBuilder(true)
val customExtractor(result) = "test"
"test" match {case customExtractor(result) => result}

Когда вы делаете один пользовательский экстрактор, это не имеет большого значения, но если вы создаете большой список экстракторов для оператора case, это может усложнить чтение, отделив все экстракторы от их использования. .

Я ожидаю, что ответ - нет, вы не можете этого сделать, но я подумал, что сначала спрошу: D

Ответы [ 5 ]

8 голосов
/ 16 марта 2010

Параметризация экстракторов была бы крутой, но у нас нет ресурсов для их реализации прямо сейчас.

4 голосов
/ 09 марта 2010

Нет.

8.1.7 Шаблоны экстрактора

Схема экстрактора x (p 1, ..., p n), где n ≥ 0 одинаково синтаксическая форма как конструктор шаблон. Однако вместо дела класс, стабильный идентификатор х обозначает объект, который имеет метод-член названный unapply или unapplySeq, который соответствует шаблону.

2 голосов
/ 25 февраля 2014

Поздно, но в одной из моих библиотек есть плагин scalac, обеспечивающий синтаксис ~(extractorWith(param), bindings):

x match {
  case ~(parametrizedExtractor(param)) => 
    "no binding"
  case ~(parametrizedExtractor(param), (a, b)) =>
    s"extracted bindings: $a, $b"
}

https://github.com/cchantep/acolyte/blob/master/scalac-plugin/readme.md

1 голос
/ 01 декабря 2017

Можно в определенной степени настроить экстракторы, используя неявные параметры, например:

object SomeExtractorBuilder {
  def unapply(s: String)(implicit arg: Boolean): Option[String] = if (arg) Some(s) else None
}

implicit val arg: Boolean = true
"x" match {
  case SomeExtractorBuilder(result) =>
    result
}

К сожалению, это нельзя использовать, если вы хотите использовать разные варианты в одном match, так как все операторы case находятся в одной области. Тем не менее, иногда это может быть полезно.

0 голосов
/ 30 апреля 2019

Хотя то, что вы спрашиваете, не представляется возможным,
можно создать экстрактор, возвращающий контроллер
, который получает оцененное значение в части if оценки случая. В части if можно указать параметры
.

object DateExtractor {
  def unapply(in: String): Option[DateExtractor] = Some(new DateExtractor(in));
}

class DateExtractor(input:String){
  var value:LocalDate=null;
  def apply():LocalDate = value;
  def apply(format: String):Boolean={
    val formater=DateTimeFormatter.ofPattern(format);
    try{
      val parsed=formater.parse(input, TemporalQueries.localDate());
      value=parsed
      true;
    } catch {
      case e:Throwable=>{
        false
      }
    }
  }
}

Использование:

object DateExtractorUsage{
  def main(args: Array[String]): Unit = {
    "2009-12-31" match {
      case DateExtractor(ext) if(ext("dd-MM-yyyy"))=>{
        println("Found dd-MM-yyyy date:"+ext())
      }
      case DateExtractor(ext) if(ext("yyyy-MM-dd"))=>{
        println("Found yyyy-MM-dd date:"+ext())
      }
      case _=>{
        println("Unable to parse date")
      }
    }
  }
}

Этот шаблон сохраняет природу кода PartialFunction.
Я считаю это полезным, так как я большой поклонник методов collect / collectFirst, которые принимают частичную функцию в качестве параметра и обычно не оставляют места для предварительная обработка набора экстракторов.

...