无法将 PartialFunction 放入 scala class 构造函数中
Can't put PartialFunction in scala class constructor
似乎有一个限制,您不能在 class 构造函数中使用 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}) }
我的第一个问题是 为什么 部分函数文字需要访问 "this"。我的第二个 question/observation 是在 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)
...
最后,这个问题有好的解决方法吗?
您的第一个问题已得到解答in the comment section of this question
引用 Imm:
Anonymous classes have access to their enclosing class. The compiler doesn't know that your anonymous partial function doesn't actually access anything (and it would be very hard to check this in full generality); it simply disallows creating any anonymous classes until you're into the class proper.
为什么它会导致 REPL 崩溃是一个很好的问题,您可能应该使用此代码示例向 Typesafe 提交一张票。
解决方法非常简单,只需在 class 之外定义匿名函数,以便编译器知道您要关闭的确切状态:
object X {
val Default: PartialFunction[Any, Any] = { case x => x }
}
case class X(a: PartialFunction[Any, Any]) {
def this() = this(X.Default)
}
您的第一个问题已得到解答 。
问题是编译器限制太多,因为它不知道如何从构造函数参数块中提取内容。
其他答案中给出了解决方法,这是编译器应该对其他内容执行的操作。
另一种解决方法是手动构建:
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 中修复。
似乎有一个限制,您不能在 class 构造函数中使用 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}) }
我的第一个问题是 为什么 部分函数文字需要访问 "this"。我的第二个 question/observation 是在 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)
...
最后,这个问题有好的解决方法吗?
您的第一个问题已得到解答in the comment section of this question
引用 Imm:
Anonymous classes have access to their enclosing class. The compiler doesn't know that your anonymous partial function doesn't actually access anything (and it would be very hard to check this in full generality); it simply disallows creating any anonymous classes until you're into the class proper.
为什么它会导致 REPL 崩溃是一个很好的问题,您可能应该使用此代码示例向 Typesafe 提交一张票。
解决方法非常简单,只需在 class 之外定义匿名函数,以便编译器知道您要关闭的确切状态:
object X {
val Default: PartialFunction[Any, Any] = { case x => x }
}
case class X(a: PartialFunction[Any, Any]) {
def this() = this(X.Default)
}
您的第一个问题已得到解答
问题是编译器限制太多,因为它不知道如何从构造函数参数块中提取内容。
其他答案中给出了解决方法,这是编译器应该对其他内容执行的操作。
另一种解决方法是手动构建:
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 中修复。