def nullAs[T]: T = null.asInstanceOf[T]
val int: Int = nullAs // 0: Int
// type erasure:
case class Container[T](value: T)
implicit val charContainer: Container[Char] = Container('c')
def nullWithContainer[T](implicit container: Container[T]): T = {
println(container)
null.asInstanceOf[T]
}
val long: Long = nullWithContainer
// prints Container(c)
// 0L
3条答案
按热度按时间ac1kyiln1#
我怀疑编译器无法在
val x1: Int = test[???]
中推断Int
,因为这两个选项:以及
是有效的。所以编译器只需要猜出你指的是哪个选项。
当编译器有选择的时候,它通常会从选项中选择最小的类型,目前是
Nothing
。Why Scala Infer the Bottom Type when the type parameter is not specified?
原则上,如果你想探索左手边的类型,你可以把
test
变成macro,然后它甚至可以不是泛型的。把它变成白盒意味着它可以返回一个比声明的(Any
)更精确的类型,例如Int
。一个二个一个一个
vltsax252#
实际上,这里的类型推断没有错,这里的类型推断意味着编译器应该判断出
T
类型参数是Int
,并且从方法表达式返回的值是一个整数,这是正常工作的:您也可以尝试打印以下内容:
对于泛型类型
"ClassTag[_]"
的隐式解析没有达到预期的效果。它打印Nothing
的原因是编译器发现对象scala.reflect.ClassTag.Nothing : ClassTag[Nothing]
适合您的情况。现在关于这个新事物,在SO和互联网上有大量的内容来解释为什么会发生这种情况以及如何在不同的情况下处理它。下面是另一段代码,用于在您的情况下区分
type inference
和type erasure
:这意味着类型推断是正确的,但是类型擦除发生了,因为在运行时,
charContainer
的类型是Container
,而不是Container[Char]
。jfgube3f3#
在这一行中,你给出的
Int
是值x1
的类型,它将保存函数test
的结果,至于T
的classTag
,编译器找不到任何信息,这就是为什么它返回Nothing
,在这种情况下,它采用val x1: Int = test[Nothing]
,因此您必须始终为test
指定一个类型,否则它将打印Nothing