编译器在下面的每个类声明中看到的不同之处是导致typeOf的行为不同。 (即类声明的属性是什么导致它失败)。
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 :(得分:1)
这是一种免费类型。你不能用前缀来引用它。
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> class C { class D }
defined class C
scala> val c = new C
c: C = C@29626d54
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
本地课程无法做到的其他事情,如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
我看起来更多,但现在已经很晚了,我的REPL破了...
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)