2013-02-18 8 views
5

Ich habe ein bisschen um gesucht, aber ich war nicht in der Lage ein Beispiel einer solchen Struktur zu finden:Selfreferencing Generics

Person[P <: Person[P]] 

, die in einer Art und Weise erklärt verstehe ich.

Wie löst sich das auf? Es sieht irgendwie wie eine endlose Rekursion für mich aus, aber es scheint, dass ich mit dieser Schlussfolgerung falsch liege.

Antwort

5

Die Struktur selbst ist in der Twitter Scala School erklärt und heißt F-beschränkter Polymorphismus.

Diese Struktur wird verwendet, wenn das Merkmal einen Verweis auf den Typ des Objekts haben muss, das es erweitert. Wenn die Scala Schule Erklärung nicht genug ist, können Sie das Internet für ‚F-begrenzt Polymorphismus‘ suchen

+1

F-beschränkter Polymorphismus ... ja, ich hätte das nie finden können. Danke, ich denke, ich verstehe es jetzt. –

+0

Wo haben Sie in der letzten Zeile "erweitert", meintest du '<:'? – AmigoNico

+0

Ich bin hin und her gesprungen, um eines der beiden auszuwählen. Glaubst du '<:' wäre besser gewesen? – EECOLOR

5

Dies wird manchmal als ein Selbst Typ (nicht mit Scala explizit eingegeben Selbstverweise zu verwechseln), und es ist in der Regel Wird verwendet, um Methodensignaturen zu erhalten, die stark genug sind, um auszudrücken, dass die Methode mit Objekten des gleichen Typs wie der Empfänger arbeitet.

Schauen wir uns ein Beispiel an. Nehmen wir an, Sie haben ein Basismerkmal Animal mit einer generischen breed Methode, die eine weitere Animal übernimmt und eine Animal zurückgibt.

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

Ok, aber was Sie wirklich wollen, ist eine breed Methode, dass nur jedes konkretes Tier drückt mit den Tieren der gleichen Klasse züchtet und gibt auch ein Tier der gleichen Klasse. Die folgende Implementierung

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

ist nicht möglich, da diese breed ‚s Signatur nicht übereinstimmt. Überschreiben ist auch nicht möglich, weil Sie den Argumenttyp covariantly ändern müssen, was verboten ist.

Eigenart zur Rettung:

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

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

Wie EECOLOR bereits darauf hingewiesen, dahinter die Typentheorie ist F-Polymorphismus begrenzt genannt.

+0

Danke für das Beispiel, zusammen mit dem Link von EECOLOR Ich denke ich verstehe jetzt wirklich, wofür das in dem Code, den ich vor mir habe, gut ist ^^ –