似乎存在限制,您无法在类构造函数中使用PartialFunction
文字:
scala> case class X(a: PartialFunction[Any, Any]) { def this() = this({case x => x}) }
<console>:7: error: Implementation restriction: <$anon: Any => Any> requires premature access to class X.
case class X(a: PartialFunction[Any, Any]) { def this() = this({ case x => x}) }
我的第一个问题是为什么部分函数文字需要访问&#34;这个&#34;。我的第二个问题/观察是在Scala REPL中,再次运行相同的代码会导致REPL崩溃:
scala> case class X(a: PartialFunction[Any, Any]) { def this() = this({ case x => x}) }
java.lang.NullPointerException
at scala.tools.nsc.Global$Run.compileLate(Global.scala:1595)
at scala.tools.nsc.GlobalSymbolLoaders.compileLate(GlobalSymbolLoaders.scala:29)
at scala.tools.nsc.symtab.SymbolLoaders$SourcefileLoader.doComplete(SymbolLoaders.scala:369)
...
最后,这个问题有一个很好的解决方法吗?
答案 0 :(得分:7)
您的第一个问题已经回答in the comment section of this question
引用Imm:
匿名类可以访问其封闭类。编译器不知道你的匿名部分函数实际上没有访问任何东西(并且很难完全检查这一点);它只是不允许创建任何匿名类,直到你进入正确的类。
为什么崩溃REPL是一个很好的问题,您应该使用此代码示例向Typesafe提交一张票。
解决方法非常简单,只需在类外部定义匿名函数,以便编译器知道您要关闭的确切状态:
object X {
val Default: PartialFunction[Any, Any] = { case x => x }
}
case class X(a: PartialFunction[Any, Any]) {
def this() = this(X.Default)
}
答案 1 :(得分:1)
您的第一个问题已经回答in the comment section of this question。
问题是编译器限制性太强,因为它不知道如何从构造函数参数块中解除东西。
解决方法在另一个答案中给出,这是编译器应该用其他东西做的。
另一种解决方法是手动构建:
case class X(a: PartialFunction[Any, Any]) { def this() = this({
class $anonfun extends runtime.AbstractPartialFunction[Any, Any] {
override def applyOrElse[A, B >: Any](x: A, default: A => B): B = x match {
case x => x
//case _ => default(x) // completeness
}
override def isDefinedAt(x: Any) = x match {
case x => true
//case _ => false
}
}
new $anonfun()
})
}
第二个问题的答案是SI-9170,修正为2.11.7。