2016-04-13 11 views
1

に私は次のコードを書く:私は戻り値の型がList[Bird]ことが期待どのように解釈する:: Scalaの

def ::[B >: A] (x: B): List[B] = 
    new scala.collection.immutable.::(x, this) 

::メソッドの実装は次のようになります

class Animal 
class Bird extends Animal 
val animalList = List(new Animal, new Animal) 
new Bird :: animalList 

を。なぜそれがList[Animal]ですか?

+2

'B>:A' - > BはAのスーパークラスです。' Animal'と 'Bird'の最も厳密なスーパークラスは' Animal'です。 BirdはAnimalであると推定され、AはAnimalでBはAのSuperclassであるため、この場合はB = A = Animal –

+0

という素晴らしい投稿です。 3q – cstur4

答えて

4

:で終わるメソッド名は、式の右側にオブジェクト上で呼び出されているため

animalList.::(new Bird) 

new Bird :: animalList 

desugarsのドットなしインフィックス表記法。

我々は、明示的に...型引数として

animalList.::[Bird](new Bird) 

Birdを指定した場合...それが動作しない理由を、コンパイラを教えてくれる:

error: type arguments [Bird] do not conform to method :: 's type parameter bounds [B >: Animal]

上の2つの制約があります。タイプB

  • B >: Aメソッドシグネチャの意味はBは、リストのタイプのスーパータイプ(A、ここではAnimal)でなければなりません。
  • 値の引数(new Bird)は、Bのインスタンスでなければなりません(メソッドの引数は共変です)。

コンパイラは、これらの制約の両方を満たす最も具体的な型を選択します。これはAnimalです。

animalList.::[Animal](new Bird) 
+0

私は、 "中置記法はデュガール(...)"というのは本当だとは思わない。それはメソッドであり、あなたがそれを提示したときに呼び出すことはできません 'animalList.::(newバード)'にdesugars。 '::(new Bird、animalList)'は '::'のコンパニオンオブジェクトのメソッドを適用するため、動作します(バッククックは不要です)。終わりには両方とも '::'のコンストラクタを呼び出します。 –

+0

@ŁukaszAh、ありがとう。私はScalaとHaskellを混乱させています。 OOPは複雑です;)修正。 –

関連する問題