Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala程序中的推断类型_Scala_Type Inference_Read Eval Print Loop - Fatal编程技术网

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

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: 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对象,其中包含编译期间生成的类型信息。