鉴于:
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代码时遇到了这个问题,而且工作正常.
你已经遇到了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绑定中.
它不会编译,因为T它不会出现在参数列表中的任何位置,因此无法推断(或者更确切地说,它被推断Nothing).
你可以像这样解决它:
def something [T] (foo : Class[_ <: Foo[T]]): T = foo.newInstance.get
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |