【问题标题】:Can't put PartialFunction in scala class constructor不能将 PartialFunction 放在 scala 类构造函数中
【发布时间】:2015-06-13 20:46:46
【问题描述】:

似乎有一个限制,您不能在类构造函数中使用 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”。我的第二个问题/观察是,在 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)
    ...

最后,这个问题有没有好的解决方法?

【问题讨论】:

标签: scala partialfunction


【解决方案1】:

您的第一个问题已回答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)
}

【讨论】:

    【解决方案2】:

    您的第一个问题已回答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。

    【讨论】:

      猜你喜欢
      • 2016-04-11
      • 1970-01-01
      • 2013-03-16
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多