2015-06-18 14 views
7

Gibt es eine Möglichkeit, eine Sammlung von Alternativen eines gemeinsamen Typ zu definieren:Scala - sich gegenseitig ausschließende Merkmale

trait Mutability 
trait Mutable extends Mutability 
trait Immutable extends Mutability 

und haben den Compiler schließt so etwas wie:

object Hat extends Mutable with Immutable 

Ich glaube, ich kann Kraft einige Compiler-Fehler, eine gemeinsame, in Konflikt Element durch, jedoch die Fehlermeldung ist ein bisschen schräg:

trait Mutability 
trait Mutable extends Mutability { protected val conflict = true } 
trait Immutable extends Mutability { protected val conflict = true } 

object Hat extends Mutable with Immutable 

<console>:10: error: object Hat inherits conflicting members: 
value conflict in class Immutable$class of type Boolean and 
value conflict in class Mutable$class of type Boolean 
(Note: this can be resolved by declaring an override in object Hat.) 
    object Hat extends Immutable with Mutable 

Gibt es eine direktere Möglichkeit, diese Einschränkung auszudrücken und es nicht jemandem zu erlauben, damit umzugehen, indem man den Hinweis des Compilers nimmt (Override 'Konflikt' in Hat)?

Dank für irgendwelche Einsichten

+0

Welches Ziel erreicht dies? Ich kann mich an keine Zeit erinnern, die ich jemals wollte. – Daenyth

+0

Zuerst, danke für die unten stehenden Ideen, immer noch darüber nachdenkend, ob ich eine luftdichte Lösung bekommen kann (das erlaubt den allzu einfachen Fehler nicht ") MutabilityLevel [Mutability] "Durchrutschen". Zweitens, was das Ziel betrifft. Es gibt zwei Zielebenen: (1) Merkmalsmerkmal, um Handlern zu signalisieren, dass sie Aktualisierungsereignisse für Instanzen dieses Typs nicht sicher handhaben können, und (2) das Veränderbare Merkmal tatsächlich erweitern, um diese Ereignisse zu definieren: Klasse Ereignisse [T <: Veränderbar ] { Fallklasse Hinzufügen (T) Fallklasse Entfernen (T) } zum Beispiel. – jmcnulty

+0

'Klasse Mat (name: String) erstreckt Mutable' ' Klasse-A erweitert Immutable' Handlers sicher davon ausgehen, dass kann 'Objekt PatEvents erstreckt Events [Pat]' kann nicht kompilieren und 'PatEvents.Add/Remove' existieren nicht – jmcnulty

Antwort

3

Ich denke, das

sealed trait Mutability 
case object Immutable extends Mutability 
case object Mutable extends Mutability 

trait MutabilityLevel[A <: Mutability] 

class Foo extends MutabilityLevel[Immutable.type] 
funktionieren könnte

Diese (ab?) Nutzt die Tatsache, dass Sie das gleiche Merkmal nicht verlängern kann zweimal mit unterschiedlicher Parametrierung

scala> class Foo extends MutabilityLevel[Immutable.type] with MutabilityLevel[Mutable.type] 
<console>:11: error: illegal inheritance; 
self-type Foo does not conform to MutabilityLevel[Immutable.type]'s selftype MutabilityLevel[Immutable.type] 
     class Foo extends MutabilityLevel[Immutable.type] with MutabilityLevel[Mutable.type] 
         ^
<console>:11: error: illegal inheritance; 
self-type Foo does not conform to MutabilityLevel[Mutable.type]'s selftype MutabilityLevel[Mutable.type] 
     class Foo extends MutabilityLevel[Immutable.type] with MutabilityLevel[Mutable.type] 

Jedoch

scala> class Foo extends MutabilityLevel[Mutability] 
defined class Foo 
+0

Sie könnte das beheben, indem man "MutabilityLevel" versiegelt und eine weitere Ebene hinzufügt, z 'trait Immutable erweitert MutabilityLevel [MutabilityLevel.I]'. –

+0

@JCracknell Anrufer könnten dann Unveränderlich erweitern und es unsachgemäße Implementierungen geben. – Daenyth

+0

Ja, jedoch würde dies die Erstellung eines "MutabilityLevel [Mutability]" verhindern. –

Verwandte Themen