2010-08-06 5 views
9

sagen, dass ich die folgenden Merkmale haben:Selbst Typ Vererbung in scala

trait A 

trait B { this: A => } 

trait C extends B // { this: A => } 

Compiler-Fehler: illegal inheritance; self-type C does not conform to B's selftype B with A
Wie erwartet, wenn ich die Selbst Typenannotation Kommentar-, der Compiler ist glücklich.

Ich denke es ist ziemlich offensichtlich, warum C auch diesen Selbsttyp braucht. Was ich nicht verstehe, warum es nicht von A "erben" kann, wenn der Compiler bereits herausfinden könnte, dass es benötigt wird?

Ich denke, es könnte die Ausführlichkeit reduzieren, wenn Sie Selbsttypen mit komplizierten Hierarchien verwenden, vor allem, wenn Sie eine große Gruppe von Eigenschaften mischen, von denen jeder seinen eigenen Typ hat.

Ich denke wahrscheinlich gibt es einen guten Grund für das aktuelle Verhalten, ich konnte einfach nicht herausfinden, was es ist.

Zuerst dachte ich, es könnte mit der Linearisierung zusammenhängen, aber es scheint mir, dass es hier nicht spielt (auch wenn ich mehr Eigenschaften mit komplizierteren Selbsttypen gemischt hätte).

Würde es in einigen Fällen zu Mehrdeutigkeiten führen? Wenn ja, warum kann es nicht funktionieren, wenn es keine Zweideutigkeit gibt?

Oder hängt es mit einigen Schwierigkeiten bei der richtigen Umsetzung davon zusammen?

Ich könnte einige Diskussionen über das Thema (wie self type is not inherited) finden, aber sie geben meist nur das Problem und schlussfolgern, dass es so ist, ohne zu viel Erklärung und/oder eine Lösung (wenn es existiert).

Antwort

1
trait C extends B with A 

ist nicht die einzige Lösung. Sie könnte auch

trait AA extends A 
trait C extends B with AA 

Das heißt, alles, was die Schnittstelle von A erbt akzeptiert wird. Wenn Sie sich auf eine konkrete Implementierung verlassen müssen, würden Sie ein Mixin wählen; Wenn die Implementierung dem Benutzer überlassen ist oder Sie einen guten Grund haben, das Merkmal nicht im Merkmal zu spezifizieren (zum Beispiel, um Abhängigkeitsprobleme zu lösen), würden Sie es zu einem Selbst-Typ machen.

+1

Ich denke, es ist klar für mich, was ist der Unterschied zwischen dem Mischen in einem Merkmal oder machen Sie es zu einem Selbst-Typ. Meine Frage ist: Angenommen, ich möchte die vorherigen Merkmale mit Selbst-Typ und Mischen so wie es ist und der Compiler kann herausfinden, dass ich (mindestens) A als Selbst-Typ von C brauche, warum kann es es nicht automatisch "hinzufügen"? –

+0

Ich denke, das wäre in vielen Fällen unerwünscht, da es dann kompilieren würde, ohne Ihnen die Möglichkeit zu geben, die Klasse zu spezialisieren. Und was tun, wenn 'A' im aktuellen Umfang nicht verfügbar ist? Ich glaube, das wäre verwirrend und Vererbung und Vermischung sollten explizit gemacht werden. Wenn Sie die Typisierung speichern möchten, können Sie auch eine 'Eigenschaft definieren CA erweitert C mit A' und diese verwenden. – Debilski

+1

Debilski, Sie missverstehen die Frage. Das OP möchte, dass "Merkmal C erweitert B" gleichbedeutend ist mit "Merkmal C erweitert B {dies: A =>}", nicht "Merkmal C erweitert B mit A". – Blaisorblade