Scala:为什么不编译?

Pab*_*dez 5 generics scala

鉴于:

class Foo[T] {
 def get: T
}

class Bar
class FooBar extends Foo[Bar] {
 def get = new Bar
}

object Baz {
    def something [T, U <: Foo[T]] (foo : Class[U]): T = foo.newInstance.get
}
Run Code Online (Sandbox Code Playgroud)

我应该可以做这样的事,对吧?

Baz.something(classOf[FooBar])
Run Code Online (Sandbox Code Playgroud)

奇怪的是这是扔:

inferred type arguments [Nothing,this.FooBar] do not conform to method something's type parameter bounds [T,U <: this.Foo[T]]
Run Code Online (Sandbox Code Playgroud)

这很奇怪:S.BTW我在迁移一些与我在这里写的东西相当的java代码时遇到了这个问题,而且工作正常.

Tra*_*own 6

你已经遇到了Scala类型推断的一个更烦人的限制!请参阅此答案,以清楚地解释编译器在此处窒息的原因.

你有一些选择.最简单的是你可以自己提供类型:

Baz.something[Bar, FooBar](classOf[FooBar])
Run Code Online (Sandbox Code Playgroud)

但那令人讨厌的冗长.如果你真的不在乎U,可以将它从类型参数列表中删除:

object Baz {
  def something[T](foo: Class[_ <: Foo[T]]): T = foo.newInstance.get
}
Run Code Online (Sandbox Code Playgroud)

现在FooBar将在您的示例中正确推断.您还可以使用上面链接的答案中讨论的技巧:

object Baz {
  def something[T, U <% Foo[T]](foo: Class[U]): T = foo.newInstance.get
}
Run Code Online (Sandbox Code Playgroud)

为什么这个工作有点棘手 - 关键是在视图绑定后,T不再出现在U绑定中.


Rég*_*les 5

它不会编译,因为T它不会出现在参数列表中的任何位置,因此无法推断(或者更确切地说,它被推断Nothing).

你可以像这样解决它:

def something [T] (foo : Class[_ <: Foo[T]]): T = foo.newInstance.get
Run Code Online (Sandbox Code Playgroud)