2015-06-13 7 views
6

Sembra che ci sia una limitazione che non è possibile utilizzare PartialFunction letterali in costruttori della classe:Non si può mettere in funzione parziale costruttore della classe scala

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}) } 

mia prima domanda è il motivo per cui ha bisogno un letterale funzione parziale accesso a "questo". La mia seconda domanda/osservazione è che nella Scala REPL, in esecuzione di nuovo lo stesso codice si blocca il 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) 
    ... 

E, infine, c'è una buona soluzione per questo problema?

+1

Vedere [SI-8593] (https://issues.scala-lang.org/browse/SI-8593). Relativo anche: https://groups.google.com/forum/#!topic/scala-user/V085Tg0mKcU –

risposta

7

La tua prima domanda si risponde in the comment section of this question

Citando Imm:

classi anonime hanno accesso alla loro classe racchiude. Il compilatore non sa che la tua funzione anonima parziale non accede effettivamente a nulla (e sarebbe molto difficile controllarla in tutta generalità); semplicemente non consente di creare classi anonime finché non si entra nella classe corretta.

Perché si blocca il REPL è una buona domanda, probabilmente dovresti inviare un ticket a Typesafe con questo esempio di codice.

Una soluzione è abbastanza semplice, basta definire la funzione anonima al di fuori della classe in modo che il compilatore conosce l'esatto stato si sta chiudendo sopra:

object X { 
    val Default: PartialFunction[Any, Any] = { case x => x } 
} 

case class X(a: PartialFunction[Any, Any]) { 
    def this() = this(X.Default) 
} 
1

La tua prima domanda si risponde in the comment section of this question.

Il problema è che il compilatore è troppo restrittivo perché non sapeva come estrarre materiale dal blocco dei parametri del costruttore.

La soluzione alternativa è data nell'altra risposta, che è ciò che il compilatore dovrebbe fare con quell'altra roba.

L'altra soluzione è la costruzione manuale:

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() 
    }) 
} 

La risposta alla tua seconda domanda è che è SI-9170, fissata per 2.11.7.

Problemi correlati