2016-04-18 5 views
2

Was sieht der Compiler anders in jeder darunter liegenden Klassendeklaration, die dazu führt, dass typeOf sich anders verhält? (d. h. was ist die Eigenschaft der Klassendeklaration, die den Fehler verursacht).Warum behandelt Scala lokal definierte Klassen anders als Klassen in äußeren Bereichen?

import org.junit.Test 
import scala.reflect.runtime.universe._ 


case class Person1(name: String) 
class ReflectTest { 

    case class Person2(name: String) 

    @Test 
    def constructorTest(): Unit = { 

    case class Person3(name: String) 

    typeOf[Person1] // Yep 
    typeOf[Person2] // No problem 
    typeOf[Person3] // No typetag information available :(
    } 
} 
+0

Mögliche Duplikat von [Scala - Keine TypTag verfügbar Ausnahme bei Verwendung der Fallklasse, um TypeTag zu erhalten?] (http://StackOverflow.com/Questions/16988558/Scala-NoTypet-Available-Exception-When-using-case-class -zu-versuchen-zu-bekommen-type) – Aivean

+0

bereits beantwortet [hier] (http://stackoverflow.com/questions/16988558/scala-no-typetag-available-exception-when-using-case-class-to-try-to-get-typet) – Aivean

+1

1) Meine Frage ist ein wenig anders: * Was sieht der Compiler *, der diesen Effekt verursacht (nicht - bitte korrigieren Sie meinen Syntaxfehler). 2) Die referenzierte Frage liefert nicht einmal genug Informationen, um das Problem zu beantworten, das der Autor als Selbstantwort akzeptiert hat. – user48956

Antwort

1

Es ist ein freier Typ. Und Sie können nicht mit einem Präfix darauf verweisen.

scala> import reflect.runtime.universe._ 
import reflect.runtime.universe._ 

scala> class C { class D } 
defined class C 

scala> val c = new C 
c: C = [email protected] 

scala> val x = { final class X ; weakTypeTag[X] } 
x: reflect.runtime.universe.WeakTypeTag[_ <: AnyRef] = WeakTypeTag[X] 

scala> val t = typeTag[C] 
t: reflect.runtime.universe.TypeTag[C] = TypeTag[C] 

scala> val w = typeTag[c.D] 
w: reflect.runtime.universe.TypeTag[c.D] = TypeTag[c.D] 

scala> val v = typeTag[C#D] 
v: reflect.runtime.universe.TypeTag[C#D] = TypeTag[C#D] 

scala> (t.tpe.typeSymbol, t.tpe.typeSymbol.isStatic) 
res1: (reflect.runtime.universe.Symbol, Boolean) = (class C,true) 

scala> (x.tpe.typeSymbol, x.tpe.typeSymbol.isStatic) 
res2: (reflect.runtime.universe.Symbol, Boolean) = (free type X,false) 

scala> (w.tpe.typeSymbol, w.tpe.typeSymbol.isStatic) 
res3: (reflect.runtime.universe.Symbol, Boolean) = (class D,false) 

scala> (v.tpe.typeSymbol, v.tpe.typeSymbol.isStatic) 
res4: (reflect.runtime.universe.Symbol, Boolean) = (class D,false) 

scala> reflect.runtime.universe.internal.asFreeType(x.tpe.typeSymbol) 
res5: reflect.runtime.universe.FreeTypeSymbol = free type X 

Andere Dinge, die Sie nicht mit lokalen Klassen tun, als mentioned in the spec:

scala> val x = { private class X ; weakTypeTag[X] } 
<console>:1: error: illegal start of statement (no modifiers allowed here) 
val x = { private class X ; weakTypeTag[X] } 
     ^

scala> import c.D 
import c.D 

würde ich mehr aussehen, aber es ist spät und meine REPL brach ...

scala> val y = { final class X { class Y } ; val x = new X ; import x.Y ; weakTypeTag[Y] } 
warning: there was one feature warning; re-run with -feature for details 
java.lang.AssertionError: assertion failed: x.type 
    at scala.reflect.internal.tpe.TypeMaps$adaptToNewRunMap$.adaptToNewRun(TypeMaps.scala:1106) 
    at scala.reflect.internal.tpe.TypeMaps$adaptToNewRunMap$.apply(TypeMaps.scala:1150) 
    at scala.reflect.internal.tpe.TypeMaps$adaptToNewRunMap$.apply(TypeMaps.scala:1079) 
    at scala.reflect.internal.tpe.TypeMaps$adaptToNewRunMap$.apply(TypeMaps.scala:1148) 
    at scala.reflect.internal.tpe.TypeMaps$TypeMap.mapOver(TypeMaps.scala:162) 
    at scala.reflect.internal.tpe.TypeMaps$adaptToNewRunMap$.apply(TypeMaps.scala:1197) 
    at scala.reflect.internal.tpe.TypeMaps$adaptToNewRunMap$.apply(TypeMaps.scala:1171) 
    at scala.reflect.internal.Symbols$Symbol.adaptInfos(Symbols.scala:1629) 
    at scala.reflect.internal.Symbols$Symbol.rawInfo(Symbols.scala:1581) 
    at scala.tools.nsc.typechecker.Typers$Typer.isStale(Typers.scala:504) 
    at scala.tools.nsc.typechecker.Typers$Typer.reallyExists(Typers.scala:496) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedSelectInternal$1(Typers.scala:4712) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedSelect$1(Typers.scala:4676) 
+0

https://issues.scala-lang.org/browse/SI-8446 –

Verwandte Themen