Scala类型参数推断会徒劳地失败

Scala类型参数推断会徒劳地失败,scala,type-inference,Scala,Type Inference,太好了!我可以从A的实例创建B的实例。只有一个例外。对于A[Nothing]的实例,类型推断失败 scala> class A[T] defined class A scala> class B[T](a: A[T]) defined class B scala> val b = new B(new A[Int]) b: B[Int] = B@1ff8982d 我应该为此提交一个bug,还是一个故意的陷阱来吓跑对Scala缺乏足够解决方案的程序员?答案在编译反馈中。您需要

太好了!我可以从
A
的实例创建
B
的实例。只有一个例外。对于
A[Nothing]
的实例,类型推断失败

scala> class A[T]
defined class A

scala> class B[T](a: A[T])
defined class B

scala> val b = new B(new A[Int])
b: B[Int] = B@1ff8982d

我应该为此提交一个bug,还是一个故意的陷阱来吓跑对Scala缺乏足够解决方案的程序员?

答案在编译反馈中。您需要声明A在T中是协变的,这样当您在构造新B期间没有指定类型参数时,编译器可以推断A[Nothing]可能被视为类型T(或者将A[T]参数视为T)。这是协方差背后的基本概念

自2008年以来,这一点一直为人所知并被忽视。假设没有人使用Scala做任何严肃的事情。

奇怪的是,
def[T](a:a[T])=9;f(新A[Nothing])
有效。但是
def[T](a:a[T])=a;f(新的A[Nothing])
再次失败,出现相同的
类型不匹配
。如果不是错误的话,至少会令人困惑。我会提交一个bug,使其协变,这将“使错误消失”。但是错误的原因是什么呢?为什么类型推断与
A[Int]
一起工作,而与
A[Nothing]
不一起工作?这可能是因为没有任何东西是“无人居住的”(来自Scaladoc),并且是Any的直接子类型,而Int是AnyVal的直接子类型?是的,这肯定与
Nothing
是一种非常特殊的类型有关。这不是
Any
vs
AnyVal
的问题,但是,该示例适用于除
Nothing
之外的任何类型<代码>C类;val b=new b(new A[C])有效。如果按如下定义A和b,则其有效:A类[T];B类[](a:a[])
scala> val b = new B(new A[Nothing])
<console>:9: error: type mismatch;
 found   : A[Nothing]
 required: A[T]
Note: Nothing <: T, but class A is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
       val b = new B(new A[Nothing])
scala> val b = new B[Nothing](new A[Nothing])
b: B[Nothing] = B@3aad5958