17

基本上,我希望能够构建一个自定义提取器,而不必在使用它之前将其存储在变量中。

这不是我如何使用它的真实示例,它更有可能用于正则表达式或其他一些字符串模式(如构造)的情况下,但希望它解释了我正在寻找的内容:

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}

只做一个自定义提取器并没有太大区别,但是如果您为案例语句构建大量提取器列表,则通过将所有提取器与其用法分开可能会使事情变得更难阅读。

我希望答案是否定的,你不能这样做,但我想我会先问问周围的人:D

4

5 回答 5

8

参数化提取器会很酷,但我们现在没有资源来实现它们。

于 2010-03-16T13:45:06.757 回答
4

没有。

8.1.7 提取器模式

提取器模式 x (p 1 , . . . . , pn ) 其中 n ≥ 0 与构造器模式具有相同的句法形式。但是,稳定标识符 x 不是案例类,而是表示一个对象,该对象具有与模式匹配的名为 unapply 或 unapplySeq 的成员方法。

于 2010-03-09T20:10:51.020 回答
2

晚了,但在我的一个提供语法的 lib 中有一个 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

于 2014-02-25T01:30:02.020 回答
2

可以使用隐式参数在一定程度上自定义提取器,如下所示:

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
}

不幸的是,当您想在 one 中使用不同的变体时,不能使用它match,因为所有case语句都在同一范围内。尽管如此,它有时还是有用的。

于 2017-12-01T13:04:48.150 回答
0

尽管您所要求的内容不可能直接实现,
但可以创建一个提取器返回一个容器,该容器
在案例评估的 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 方法,它们将部分函数作为参数,并且通常不会为预先创建一组提取器留出空间。

于 2019-04-30T14:08:38.407 回答