似乎TypeTags
仅适用于被调用方法的参数中使用的类型参数,而不适用于返回类型:
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.reflect.runtime.universe._
object Test {
def withParam[T: TypeTag](v: T): T = {
println(typeOf[T])
0.asInstanceOf[T]
}
def justReturn[T: TypeTag](): T = {
println(typeOf[T])
0.asInstanceOf[T]
}
}
// Exiting paste mode, now interpreting.
import scala.reflect.runtime.universe._
defined module Test
scala> val i: Int = Test.withParam(17)
Int
i: Int = 0
scala> val j: Int = Test.justReturn()
Nothing
j: Int = 0
这与2.9中Manifest的行为一致,但有什么理由不能完成,还有其他方法可以达到这个效果吗?
答案 0 :(得分:2)
要扩展Rex Kerr的评论,T
案例中justReturn
的驱动推断没有任何内容。如果你提供(合适的)类型参数,你得到这个:
scala> val j: Int = Test.justReturn[Int]()
Int
j: Int = 0
如果您将justReturn
更改为:
def justReturn[T: TypeTag]() {
println(typeOf[T])
}
...然后你可以这样做:
scala> justReturn[String]()
String
scala> justReturn[java.io.File]()
java.io.File
答案 1 :(得分:2)
类型系统以最严格的类型(即Nothing
开始,其中不存在任何实例;如果存在,它将是一个神圣的价值能够代替任何东西并做任何事情)。然后根据需要扩大类型,但由于返回处于逆变位置,因此没有理由扩大。如果您确实可以返回Nothing
,则可以在所有情况下进行设置。
然后通过告诉0
是Nothing
的实例来破坏类型系统。当然,这是完全错误的,但是编译器尽职尽责地相信你,并且通过将它分配给Int
来拯救这种情况,这就是它一直以来的真实情况。 (它也会愉快地尝试将它分配给String
,然后你会在运行时获得异常,因为那时它是荒谬的。)
理论上可以采用不同的方式,但这是类型推理算法的一个非常基本的部分。