2013-02-18 17 views
5

は、私は少しの周りに検索したが、私はこのような構造の例を見つけることができませんでした:Selfreferencingジェネリック

Person[P <: Person[P]] 

は、私は理解してのように説明されています。

これはどのように解決されますか?私には無限の再帰のように見えますが、私はその結論が間違っているようです。

答えて

5

構造自体はTwitter Scala Schoolで説明されており、Fバウンド型多型と呼ばれています。

// you define it like this 
trait X extends Person[X] 

// it then gets expanded to this 
trait Person[X extends Person[X]] 

この構造体は、それが拡張しているオブジェクトの型への参照を持つ必要がある場合に使用されます。 Scalaの学校の説明が十分でない場合は、「F-囲まれた多型」

+1

Fに拘束された多型...そう、私はそれを見つけることができなかったでしょう。ありがとう、私は今それを得ると思います。 –

+0

最後の行に 'extend'がある場合は、' <: 'を意味しましたか? – AmigoNico

+0

私は2つのうちの1つを選択するために前後にジャンプしています。あなたは '<:'はもっと良くなっただろうと思いますか? – EECOLOR

5

これは時々セルフタイプと呼ばれているため、インターネットを検索することができます(Scalaの明示的に型指定された自己参照と混同しないように)、それが普通ですこのメソッドが受信側と同じ型のオブジェクトで動作することを表現するのに十分強いメソッドシグネチャを持つために使用されます。

例を見てみましょう。たとえば、breedという汎用のAnimalメソッドは、別のAnimalをとり、Animalを返します。

trait Animal { 
    def breed(a: Animal): Animal 
} 

[OK]を、しかし、あなたが実際に欲しいのは、すべての具体的な動物は、同じクラスの動物と繁殖することを表現しbreed方法であり、また、同じクラスの動物を返します。次の実装

class Cow extends Animal { 
    def breed(c: Cow) = new Cow 
} 

breedの署名が一致しないため、実装できません。引数タイプをcovariantlyに変更する必要があるため、オーバーライドもできません。これは禁止されています。救助へ

セルフタイプ:

trait Animal[A <: Animal[A]] { 
    def breed(a: A): A 
} 

class Cow extends Animal[Cow] { 
    def breed(c: Cow) = new Cow 
} 

EECOLORがすでに指摘したように、その背後にある型理論はF-囲まれた多型と呼ばれています。

+0

例のおかげで、EECOLORからのリンクと一緒に、私が今私の目の前に持っているコードでこれが何のために良いのか分かりました^^ –