使用以下类层次结构:
trait Provider[A] {
def get(): Seq[A]
}
abstract class ProviderImpl[A] extends Provider[A] {
final override def get(): Seq[A] = Seq()
}
trait HasX {
def getX: Int
}
trait RefinedProvider[A <: HasX] extends Provider[A]
class TypedProviderImpl extends ProviderImpl[HasX] with RefinedProvider[HasX]
我希望能够做到这一点:
val provider: RefinedProvider[_] = new TypedProviderImpl()
provider.get() map (_.getX)
但它不起作用,因为provider.get()
的返回类型为Seq[Any]
,这对我来说似乎不对,因为它是RefinedProvider
,所以{{1}应该返回get()
。
问题:我可以用存在类型解决问题,但为什么编译器不能为我强制执行此操作?
Seq[_ <: HasX]
答案 0 :(得分:1)
故障单SI-2385表明这只是将A[_]
解释为A[T] forSome
{ type T >: Nothing <: Any }
的规范的一部分,如果可能的话,不会推断出更严格的界限。人们可能想知道规范是否不应该更新。
票证SI-6169似乎暗示如果推断出更严格的界限,某些事情就会停止工作。我不确定如何以及为什么。
一个小小的妥协是你可以缩短
val provider: RefinedProvider[T] forSome { type T <: HasX }
到
val provider: RefinedProvider[_ <: HasX]
答案 1 :(得分:0)
这是因为您使用通配符:_
来声明您的变量类型:val provider: RefinedProvider[_]
,_
这意味着任何类型,你可以这样做:
val provider = new TypedProviderImpl() // the compiler and IDE will auto infer **provider** type
或
val provider: RefinedProvider[HasX] = new TypedProviderImpl() // explicitly provider type