2014-11-03 7 views
6

Gibt es eine Möglichkeit zum Kompilieren Zeit Fehler (oder zumindest Warnung) beim Zuweisen von verschiedenen Typ-Aliase, die den gleichen zugrunde liegenden Typ teilen?Scala: Compile-Fehler bei Typ-Alias-Mismatch erzwingen

Mit anderen Worten sagen, ich habe diesen Code:

type Address = String 
type City = String 

def foo(x:Address) = ... 

ich einen Fehler zur Kompilierzeit erhalten möchten/Warnung, wenn ich tun:

val city: City = "Dublin" 
foo(city) 

Soweit ich das beurteilen kann, die Compiler erlaubt es, weil sie den gleichen zugrunde liegenden Typ sind.

Antwort

4

Nach meinem besten Wissen ist es nicht möglich, diese "Typ-Sicherheit", die Sie für Typ-Aliase suchen, zu bekommen. Es gibt jedoch eine Alternative zu Aliasen, die für das verwendet werden können, was Sie wünschen: Value Classes. Grundsätzlich kann eine Wertklasse einen Typ angeben, ohne ein neues Objekt zuzuweisen. Beachten Sie, dass Wertklassen, die Sie nicht für Typaliase haben, einige Einschränkungen aufweisen.

die scala Dokumentation zu zitieren:

Correctness

Ein weiterer für Wertklassen Anwendungsfall ist die Art Sicherheit eines Datentyps ohne die Laufzeitzuweisung Overhead zu bekommen. Zum Beispiel, dass ein Fragment eines Datentyps eine Entfernung darstellt, könnte wie folgt aussehen:

class Meter(val value: Double) extends AnyVal { 
    def +(m: Meter): Meter = new Meter(value + m.value) 
    } 

Code, der zwei Abstände, wie

val x = new Meter(3.4) 
    val y = new Meter(4.3) 
    val z = x + y 

nicht wirklich fügt zuteilen Sie alle Zählerinstanzen, verwenden jedoch zur Laufzeit nur primitive Doubles.

+0

Kann ich Wertfallklassen erstellen? Ich mag die neue Keyword-Verwendung nicht. –

+0

Sie können Value Case-Klassen definieren. Übrigens: Der Grund, warum Sie das 'new'-Schlüsselwort weglassen können, ist die' apply'-Methode des (generierten) Companion-Objekts, so dass Sie nicht unbedingt eine Fallklasse definieren müssen, um das Schlüsselwort los zu werden. –

+0

Ja, ich weiß, ich bevorzuge es nicht, meine eigenen Begleiter für alle Typ-Aliase zu definieren, es ist lang und langweilig^_ ^ –

3

Nr Zumindest nicht, ohne den Compiler zu modifizieren (es könnte mit einem Compiler-Plugin, oder sogar ein Makro möglich sein), und wenn Sie diese Änderung eine Menge populäre Bibliotheken gemacht dann (einschließlich der Standard Bibliothek) und Standardcodebeispiele würden nicht kompiliert.

Vielleicht möchten Sie Wertklassen verwenden, wie in @ Kulus Antwort beschrieben. Alternativ kann Scalaz Tagged Types Overhead in mehreren Situationen vermieden werden (z. B. indem sie in eine Sammlung eingefügt werden oder subst verwendet wird, um einen generischen Typ, der einen markierten Typ verwendet, sicher heraufzustufen).