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的行为是一致的,但是有什么理由做不到,有没有其他方法可以达到这个效果?
最佳答案
类型系统以最严格的类型开始(即 Nothing
,其中不能有实例;如果有,那将是一个神一般的值,可以代表任何东西并做任何事情) .然后根据需要扩大类型,但由于返回处于逆变位置,因此永远没有扩大的理由。如果您实际上可以返回一个 Nothing
,那么您将在所有情况下都被设置。
然后通过告诉它 0
是 Nothing
的实例来颠覆类型系统。当然,这是完全错误的,但编译器忠实地相信您,您通过将其分配给 Int
来挽救这种情况,这一直都是它的真实情况。 (它也会愉快地尝试将其分配给 String
,然后您将在运行时遇到异常,因为此时它是荒谬的。)
理论上这可以以不同的方式完成,但这是类型推断算法的一个非常基本的部分。
关于scala - 为什么 TypeTag 不适用于返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14913746/