scala - 为什么 TypeTag 不适用于返回类型?

标签 scala scala-2.10

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,那么您将在所有情况下都被设置。

然后通过告诉它 0Nothing 的实例来颠覆类型系统。当然,这是完全错误的,但编译器忠实地相信您,您通过将其分配给 Int 来挽救这种情况,这一直都是它的真实情况。 (它也会愉快地尝试将其分配给 String,然后您将在运行时遇到异常,因为此时它是荒谬的。)

理论上这可以以不同的方式完成,但这是类型推断算法的一个非常基本的部分。

关于scala - 为什么 TypeTag 不适用于返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14913746/

相关文章:

Scala 反序列化 : class not found

Scala Play 框架 2.2 - 如何在模板中获取有关用户登录状态的信息

scala - 为什么 sbt compile 不会将非托管资源复制到类路径?

scala - glClearColor 只显示黑屏

scala - 当scala文件有中文注释字符时如何设置scala编译器

scala - 如何在 Slick 中进行聚合查询?

scala - Scala 2.10 中的 Option.fold

scala - 在 Scala 2.10 中使用混合复杂 Java 泛型集合

scala - 光滑和按选项列过滤

scala - 使用 SBT,我怎样才能有两个不同设置的不同 proguard 任务?