2014-11-03 9 views
6

Czy istnieje sposób na uzyskanie błędu czasu kompilacji (lub co najmniej ostrzeżenia) podczas przypisywania różnych aliasów typów, które mają ten sam podstawowy typ?Scala: Wymuszenie błędu kompilacji na niedopasowaniu aliasu typu

Innymi słowy, że mam tego kodu:

type Address = String 
type City = String 

def foo(x:Address) = ... 

Chcę się błąd czasu kompilacji/ostrzeżenie jeśli robię:

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

O ile mogę powiedzieć, Kompilator pozwala na to, ponieważ są one tego samego rodzaju.

Odpowiedz

4

Zgodnie z moją wiedzą, nie jest możliwe uzyskanie tego "bezpieczeństwa typu", którego szukasz dla aliasów typu. Istnieje jednak alternatywa do wpisywania aliasów, których można użyć do tego, co chcesz: Value Classes. Zasadniczo, klasa wartości może dać ci typ bez przydzielania nowego obiektu. Zauważ, że istnieją pewne ograniczenia dla klas wartości, których nie masz dla aliasów typów.

Cytując dokumentację scala:

poprawności wykonania

Kolejny przypadek użycia dla klas wartość jest dostać bezpieczeństwo dla typu danych bez obciążania alokacji Runtime. Na przykład, fragment typ danych, który reprezentuje odległość, może wyglądać następująco:

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

kodeksu, który dodaje dwa dystanse, takie jak

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

nie będzie faktycznie alokować dowolne instancje Meter, ale będą używać tylko prymitywnych duble w czasie wykonywania.

+0

Czy mogę tworzyć klasy wartości? Nie podoba mi się nowe użycie słowa kluczowego. –

+0

Możesz zdefiniować klasy wielkości wartości. Przy okazji: Powodem, dla którego można pominąć słowo kluczowe 'new', jest metoda 'apply' (generowana) obiektu towarzyszącego, więc nie trzeba definiować klasy case, aby pozbyć się słowa kluczowego. –

+0

Tak, wiem, wolę nie definiować własnych kompanów dla wszystkich aliasów typów, jest długi i nudny^_ ^ –

3

nr Przynajmniej nie bez modyfikowania kompilator (to może być możliwe z wtyczki kompilatora, a nawet makro), a jeśli się tę zmianę wtedy dużo popularnych bibliotek (w tym standard biblioteka) i standardowe przykłady kodu nie zostałyby skompilowane.

Możesz chcieć użyć klas wartości, jak opisano w odpowiedzi @ Kulu. Alternatywnie, Scalaz Tagged Types unika się narzutu w większej liczbie sytuacji (na przykład umieszczając je w zbiorze lub stosując subst, aby bezpiecznie upcastować typ ogólny, który wykorzystuje typ oznaczony).