Scala中的动态提取器
发布时间:2020-12-16 18:30:46 所属栏目:安全 来源:网络整理
导读:我不喜欢提取器的一个原因是它们不能有参数.所以我不能像Param这样的提取器: req match { case Param("foo")(foo) = … } 动态提取器? 这是不幸的,我希望它会在某一天改变,但是今天早上我想通过使用动态特性来解决它. object Params extends Dynamic { def
我不喜欢提取器的一个原因是它们不能有参数.所以我不能像Param这样的提取器:
req match { case Param("foo")(foo) => … } 动态提取器? 这是不幸的,我希望它会在某一天改变,但是今天早上我想通过使用动态特性来解决它. object Params extends Dynamic { def selectDynamic(name: String) = new { def unapply(params: Map[String,String]): Option[String] = params.get(name) } } …希望这会允许我在模式匹配语句中使用Params,如下所示: req match { case Params.Foo(value) => // matching Map("Foo" -> "Bar"),extracting "Bar" in value 它不起作用 ……但它不起作用.似乎编译器仍然感到困惑. scala> Map("Foo" -> "bar") match { case Params.Foo(value) => value } <console>:10: error: value applyDynamic is not a member of object Params error after rewriting to Params.<applyDynamic: error>("Foo") possible cause: maybe a wrong Dynamic method signature? Map("Foo" -> "bar") match { case Params.Foo(value) => value } ^ <console>:10: error: not found: value value Map("Foo" -> "bar") match { case Params.Foo(value) => value } ^ 从那以后我觉得很惊讶 object Params { object Foo { def unapply{params: Map[String,String]): Option[String] = … } } 会工作得很好.另外,如果我先将Params.Foo分配给变量,那么一切都还可以: scala> val Foo = Params.Foo Foo: AnyRef{def unapply(params: Map[String,String]): Option[String]} = Params$$anon$1@f2106d8 scala> Map("Foo" -> "bar") match { case Foo(value) => value } warning: there were 1 feature warning(s); re-run with -feature for details res2: String = bar 这应该被视为一个错误吗? 解决方法
规范的答案是
Can extractors be customized with parameters in the body of a case statement (or anywhere else that an extractor would be used)?
但是the hacking blog提出了将参数作为任意名称传递给动态选择的技巧,正如在问题中所尝试的那样. $scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM,Java 1.8.0_60). Type in expressions for evaluation. Or try :help. scala> class X(pattern: String) { val RegExp = new { def unapplySeq(s: String) = pattern.r.unapplySeq(s) } } defined class X scala> import language._ import language._ scala> case object p extends Dynamic { def selectDynamic(pattern: String) = new X(pattern) } defined object p scala> "abcdef" match { case p.`.*(b.*d).*`.RegExp(s) => s } res0: String = bcd 由于0700中的a crashing bug与问题中显示的2.10错误不同,因此需要额外选择: scala> class RegExp(pattern: String) { def unapplySeq(s: String) = pattern.r.unapplySeq(s) } defined class RegExp scala> case object p extends Dynamic { def selectDynamic(pattern: String) = new RegExp(pattern) } defined object p scala> "abcdef" match { case p.`.*(b.*d).*`(s) => s } java.lang.NullPointerException at scala.tools.nsc.typechecker.PatternTypers$PatternTyper$class.inPlaceAdHocOverloadingResolution(PatternTypers.scala:68) 2.10中的工作示例: $scala210 -language:_ Welcome to Scala version 2.10.5 (OpenJDK 64-Bit Server VM,Java 1.7.0_95). Type in expressions to have them evaluated. Type :help for more information. scala> :pa // Entering paste mode (ctrl-D to finish) class X(key: String) { val get = new { def unapply(params: Map[String,String]): Option[String] = params.get(key) }} object Params extends Dynamic { def selectDynamic(name: String) = new X(name) } // Exiting paste mode,now interpreting. defined class X defined module Params scala> Map("Foo" -> "bar") match { case Params.Foo.get(value) => value } res0: String = bar 这类似于问题末尾所示的内容,但很明显动态选择可以这种方式使用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |