Scala程序中的推断类型
Scala REPL显示表达式的推断类型。有没有办法知道普通Scala程序中的推断类型 比如说,Scala程序中的推断类型,scala,type-inference,read-eval-print-loop,Scala,Type Inference,Read Eval Print Loop,Scala REPL显示表达式的推断类型。有没有办法知道普通Scala程序中的推断类型 比如说, val x = { //some Scala expressions } 现在我想知道x的实际类型 也许这就是你要找的 scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> def typeOf[T](x:T)( implicit tag: TypeT
val x = {
//some Scala expressions
}
现在我想知道x的实际类型 也许这就是你要找的
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> def typeOf[T](x:T)( implicit tag: TypeTag[T] ) = tag
typeOf: [T](x: T)(implicit tag: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]
scala> class Foo( a:Int )
defined class Foo
scala> trait Bar
defined trait Bar
scala> val x = new Foo(3) with Bar
x: Foo with Bar = $anon$1@62fb343d
scala> val t = typeOf(x)
t: reflect.runtime.universe.TypeTag[Foo with Bar] = TypeTag[Foo with Bar]
scala> t.tpe
res20: reflect.runtime.universe.Type = Foo with Bar
scala> t.tpe.toString
res21: String = Foo with Bar
为了证明它产生的是表达式的静态类型,而不是对象的动态类型:
scala> val l = List(1,2,3)
l: List[Int] = List(1, 2, 3)
scala> val s:Seq[Int] = l
s: Seq[Int] = List(1, 2, 3)
scala> typeOf(s)
res22: reflect.runtime.universe.TypeTag[Seq[Int]] = TypeTag[scala.Seq[Int]]
也许这就是你要找的
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> def typeOf[T](x:T)( implicit tag: TypeTag[T] ) = tag
typeOf: [T](x: T)(implicit tag: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]
scala> class Foo( a:Int )
defined class Foo
scala> trait Bar
defined trait Bar
scala> val x = new Foo(3) with Bar
x: Foo with Bar = $anon$1@62fb343d
scala> val t = typeOf(x)
t: reflect.runtime.universe.TypeTag[Foo with Bar] = TypeTag[Foo with Bar]
scala> t.tpe
res20: reflect.runtime.universe.Type = Foo with Bar
scala> t.tpe.toString
res21: String = Foo with Bar
为了证明它产生的是表达式的静态类型,而不是对象的动态类型:
scala> val l = List(1,2,3)
l: List[Int] = List(1, 2, 3)
scala> val s:Seq[Int] = l
s: Seq[Int] = List(1, 2, 3)
scala> typeOf(s)
res22: reflect.runtime.universe.TypeTag[Seq[Int]] = TypeTag[scala.Seq[Int]]
表达式的类型在编译时是静态已知的 要在运行时访问它,可以使用另一个答案中的
TypeTag
,或一个普通宏:
scala> import scala.language.experimental.macros
import scala.language.experimental.macros
scala> import reflect.macros.blackbox.Context
import reflect.macros.blackbox.Context
scala> def impl(c: Context)(x: c.Expr[Any]): c.Expr[String] = { import c.universe._
| c.Expr[String](Literal(Constant(c.typecheck(x.tree.duplicate).tpe.toString))) }
impl: (c: scala.reflect.macros.blackbox.Context)(x: c.Expr[Any])c.Expr[String]
scala> def f(x: =>Any) = macro impl
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
defined term macro f: (x: => Any)String
scala> trait A; trait B extends A; trait C extends A
defined trait A
defined trait B
defined trait C
scala> f(List(new B{}, new C{}))
res2: String = List[A]
REPL还只报告编译器分配给表达式树的类型。表达式的类型在编译时是静态已知的 要在运行时访问它,可以使用另一个答案中的
TypeTag
,或一个普通宏:
scala> import scala.language.experimental.macros
import scala.language.experimental.macros
scala> import reflect.macros.blackbox.Context
import reflect.macros.blackbox.Context
scala> def impl(c: Context)(x: c.Expr[Any]): c.Expr[String] = { import c.universe._
| c.Expr[String](Literal(Constant(c.typecheck(x.tree.duplicate).tpe.toString))) }
impl: (c: scala.reflect.macros.blackbox.Context)(x: c.Expr[Any])c.Expr[String]
scala> def f(x: =>Any) = macro impl
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
defined term macro f: (x: => Any)String
scala> trait A; trait B extends A; trait C extends A
defined trait A
defined trait B
defined trait C
scala> f(List(new B{}, new C{}))
res2: String = List[A]
REPL还只是报告编译器分配给表达式树的类型。
val x:String={}
这就是您所指的类型吗?是的,在某些情况下,很容易知道推断的类型(在本例中为String),但在其他一些情况下,它可能更复杂。所以您想在运行时检查它是什么类型?像if(x.isInstanceOf[String])
?不,我想编程打印推断的类型是String,就像在REPL上一样。对不起,我对REPL不太熟悉。据我所见,它打印出的类型像x:java.lang.String=abc
,对吗?val x:String={}
这就是您所指的类型吗?是的,在某些情况下,很容易知道推断的类型(在本例中为String),但在其他一些情况下,它可能更复杂。所以您想在运行时检查它是什么类型?像if(x.isInstanceOf[String])
?不,我想编程打印推断的类型是String,就像在REPL上一样。对不起,我对REPL不太熟悉。据我所见,它打印出的类型类似于x:java.lang.String=abc
,对吗?Scala REPL在内部使用什么?REPL早在引入类型标记之前就存在了,所以至少有一次REPL没有使用它们。我对REPL的实现不太了解,但很明显它编译了您输入的代码;也许类型信息是编译器API提供的一部分。也许您真正想知道的是,从TypeTag中获得的结果是否与从REPL中获得的结果相同,或者其他类似类型的信息。它们是一样的;当您像我们在这里所做的那样使用TypeTag时,编译器只会创建一个TypeTag对象,其中包含编译期间生成的类型信息。Scala REPL在内部使用什么?REPL在引入TypeTag之前很久就存在了,因此至少有一次REPL没有使用它们。我对REPL的实现不太了解,但很明显它编译了您输入的代码;也许类型信息是编译器API提供的一部分。也许您真正想知道的是,从TypeTag中获得的结果是否与从REPL中获得的结果相同,或者其他类似类型的信息。它们是一样的;当您像我们在这里所做的那样使用TypeTag时,编译器只创建一个TypeTag对象,其中包含编译期间生成的类型信息。