0

簡単な質問。::クラス不変のメソッドListは次のように定義されます。

封印された抽象クラスリスト[+A]..。

def :: [B>:A](x:B):リスト[B]

私が持っているとしましょう:

class Fruit
class Mango extends Fruit
scala> val d:List[Fruit] = List.empty[Fruit]
d: List[Fruit] = List()

scala> new Mango :: d
res5: List[Fruit] = List(Mango@272d6774)

今、私はここで混乱しています。::宣言によると、引数の型は反変でなければなりません。つまり、この場合は、そのようなクラスです>: Fruit(なぜそのように作成されているのか理解しています)。しかし、私が得られMango <: Fruitないのは、、では、なぜコンパイラはエラーをスローしないのですか?

4

2 に答える 2

5

がまだであるという理由だけで、不変であったとしても、にを追加Mangoすることができます。単純な古いJavaリストの観点から考えてみてください。dListMangoFruit

val d = new java.util.ArrayList[Fruit]
d.add(new Mango)

したがって、共変性はサブタイプを追加する機能を制限しません。スーパータイプを追加し、コンパイラーによってチェックされたリストタイプをそこから取り戻すことができます。

val d: List[Fruit] = Nil
val a: List[Plant] = new Carrot :: d
于 2013-02-15T12:13:10.540 に答える
3

行で

new Mango :: d

コンパイラが次のように推論することを期待します:「new MangoタイプがMangoあり、dタイプList[Fruit]があるので、タイプList[Fruit].::(Mango)チェックする必要がありますが、そうではありません」。この場合、それは確かにエラーになります。

しかし実際には、理由は異なります。「タイプチェックが必要なnew Mango :: dので、次のようタイプnew Mangoが必要です。そのようなタイプはありますか?はい、。」したがって、エラーはありません。BB :> FruitBB = Fruit

于 2013-02-15T13:02:08.243 に答える