1

我试图了解 Scala 集合的协方差。我有以下内容:

abstract class MediaFormat{
    def name:String
    def status:String
}

case class H264_high(status:String="on") extends MediaFormat {
    def name = "h264_high"
}
case class H264_med(status:String="on") extends MediaFormat {
    def name = "h264_med"
}
case class H264_low(status:String="on") extends MediaFormat {
    def name = "h264_low"
}
case class H264_syndication(status:String="off") extends MediaFormat {
    def name = "h264_syndication"
}

我想做的是拥有一组所有这些格式,因为我需要一个集合,其中每种格式只出现一次,所以我尝试了:

object MediaFormat {
    val allFormats:Set[MediaFormat] = Set(H264_high,H264_low)
}

这给了我一个编译时异常,因为据我所知,Set 是不变的。

所以我想,我想我只需要使用一个 List 并自己管理重复的值

但后来我试试这个:

object MediaFormat {
    val allFormats:List[MediaFormat] = List(H264_high,H264_low)
}

因为据我了解, List协变的,但仍然无法编译。

有人可以帮助我了解我应该做些什么来收集我的格式吗?

4

1 回答 1

7

它无法编译,因为您引用的是伴随对象(模块),而不是案例类!编译错误(您应该已经发布)与方差无关。如果您这样做,它将起作用:Set

val allFormats: Set[MediaFormat] = Set(H264_high(), H264_low())
                                                ^^          ^^

或者,

val allFormats = Set[MediaFormat](H264_high(), H264_low())

但是,鉴于您对问题的描述,将这些作为案例类是没有意义的;我只会让它们成为模块,即

case object H264_syndication extends MediaFormat {
  def status = "off"
  def name = "h264_syndication"
}

然后你的原始代码就可以正常工作了。或者我会让它们如下所示:

case class MediaFormat(status: String, name: String)
val H264_syndication = MediaFormat(status ="off", name = "h264_syndication")

我认为这是我的偏好;老实说,我很少再使用抽象类了(通常,我是不诚实的)。


解释:协方差的含义如下:

G[S] <: G[T]当且当S <: T

不变的事实Set意味着 aSet[S]不是Set[T](for S <: T) 的子类型,但这并不意味着这样的 aSet[T]可能不包含type的元素S

于 2012-06-27T16:11:32.300 回答