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"
}

私がやりたかったのは、これらすべての形式のセットを用意することでした。各形式が1回だけ発生するコレクションが必要なので、次のことを試しました。

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

私が今理解しているように、Setは不変であるため、これによりコンパイル時の例外が発生しました。

ですから、リストを使用して、繰り返される値を自分で管理する必要があると思います。

しかし、私はこれを試します:

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

私が理解しているように、List共変ですが、それでもコンパイルされません。

誰かが私のフォーマットのコレクションを取得するために何をすべきかを理解するのを手伝ってもらえますか?

4

1 に答える 1

7

It doesn't compile because you are referencing the companion object (module), not the case classes! The compile error (which you should have posted) is nothing to do with variance. It will work, with Set if you do this:

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

Or alternatively;

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

However, it makes no sense for these to be case classes given your description of the problem; I would just make them modules, i.e.

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

Then your original code will work just fine. Or I would make them vals as follows:

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

I think this would be my preference; I rarely use abstract classes any more to be honest (normally, I am dishonest).


Explanation: Covariance means the following:

G[S] <: G[T] iff S <: T

The fact that Set is invariant, means that a Set[S] is not a subtype of Set[T] (for S <: T), but it does not mean that such a Set[T] may not contain elements of type S.

于 2012-06-27T16:11:32.300 に答える