我一直在使用2.11中的编译器和repl的新API,并且遇到了一些奇怪的事情。这是我的repl输出:
Welcome to Scala version 2.11.0-20140415-163722-cac6383e66 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.tools.nsc.interpreter.IMain
import scala.tools.nsc.interpreter.IMain
scala> import scala.tools.nsc.Settings
import scala.tools.nsc.Settings
scala> val eng = new IMain(new IMain.Factory(), new Settings())
eng: scala.tools.nsc.interpreter.IMain = scala.tools.nsc.interpreter.IMain@649b982e
scala> eng.interpret("val x: Int = 2")
x: Int = 2
res0: scala.tools.nsc.interpreter.IR.Result = Success
scala> eng.valueOfTerm("x")
res2: Option[Any] = Some(2)
scala> eng.typeOfTerm("x")
res3: eng.global.Type = ()Int
scala> eng.typeOfExpression("x")
res4: eng.global.Type = Int
scala> eng.typeOfExpression("x") =:= eng.global.definitions.IntTpe
res6: Boolean = true
scala> eng.typeOfTerm("x") =:= eng.global.definitions.IntTpe
res7: Boolean = false
如您所见,typeOfTerm("x")
会返回()Int
,但typeOfExpression("x")
会返回Int
。我认为类型()Int
代表Int
类型的变量,但我无法确定。如果有人可以确认或纠正我的困惑,并可能指示我谈论这个问题的任何文件,我会很感激。我查看了我能找到的反思文档,但没有任何运气。
答案 0 :(得分:1)
在REPL中,您的val x
不是本地定义。它包含在一个类或对象中,这会导致不同的行为。
您的object X { val x = 2 }
的成员x
是无参数的方法类型,就好像您有def x = 2
一样。
scala> val x: Int = 2
x: Int = 2
scala> $intp.typeOfTerm("x")
res0: $intp.global.Type = ()Int
scala> import $intp.global._
import $intp.global._
scala> $intp.replScope.lookup(TermName("x"))
res2: $intp.global.Symbol = value x
scala> res2.tpe
res3: $intp.global.Type = ()Int
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._, definitions._ also imported **
** Try :help, :vals, power.<tab> **
scala> intp.replScope.lookup(TermName("x"))
res6: $r.intp.global.Symbol = value x
这就是我们习惯看到它的方式:
scala> .tpe
res7: $r.intp.global.Type = => Int
scala> :phase
Active phase is 'Typer'. (To clear, :phase clear)
scala> :phase clear
Cleared active phase.
scala> res6.tpe
res8: $r.intp.global.Type = ()Int