我只是写了一些scala代码:
class Cat[T]
val x: Cat[_ <: String] = new Cat[String]
它可以编译,但我不太了解。
您可以看到我将x
的类型声明为Cat[_ <: String]
,这意味着
Cat[ T forSome { type T <: String; }]
但是,当x
具有此特殊类型时,我该怎么办?是否有任何条件我必须声明x
这样以便以后使用?
答案 0 :(得分:1)
你不明白,因为你选了一个糟糕的例子。这与Java方差完全相同,因此,例如,您可以这样做:
import java.utii.{ArrayList, List => JList}
val x: JList[_ <: Object] = new ArrayList[String]
尽管Java的List
及其实现类不是共同变体(因为Java中没有这样的概念,除其他外),你可以声明&#39; X&#39;是一个&#34;共同变体&#34; List
,并为其指定一个子类,在本例中为Object
。
您的示例很糟糕,因为您选择Cat[String]
而不是Cat
的子类的String
。
答案 1 :(得分:0)
Cat
中Cat[_ <: String]
的类型参数是一种存在类型。他们的动机很大程度上与Java的通配符相当,因此Scala可以继续与Java互操作,尽管它是(精神病)泛型。引用Martin Odersky intervew:
比尔维纳斯:如果不这样做,你会添加存在类型吗? 需要担心Java兼容性问题的原因 类型和擦除。如果Java已经确定了类型,没有原始类型或 通配符,Scala会有存在类型吗?Martin Odersky:如果Java已经确定了类型,没有原始类型或 通配符,我认为我们不会对存在主义有太多用处 类型,我怀疑他们会在Scala。
这是一个blog post,其中一个Scala开发人员在将它们添加到语言时讨论了存在类型。通过更深入地讨论它们来blog post。
答案 2 :(得分:0)
但是,当它具有这种特殊类型时,我能用x做什么?
这种类型并不特别特别。你可以,例如将它传递给采用此类型的方法等,但如果您将其声明为Cat[String]
,那么您也可以这样做,这是更具体的
是否有任何条件我必须声明x这样以供以后使用?
一种可能性是您希望覆盖x
:
class Foo {
val x: Cat[_ <: Object] = new Cat[Object]
}
class Bar extends Foo {
override val x: Cat[_ <: Object] = new Cat[String]
}
class Baz extends Bar {
override val x: Cat[_ <: Object] = new Cat[File]
}
如果没有Foo
和Bar
中的类型签名,这些覆盖都不可能。