2014-11-03 1 views
6

Есть ли способ получить ошибку времени компиляции (или, по крайней мере, предупреждение) при назначении псевдонимов типов, которые имеют один и тот же базовый тип?Scala: принудительная ошибка компиляции при несоответствии псевдонимов типа

Другими словами, у меня есть этот код:

type Address = String 
type City = String 

def foo(x:Address) = ... 

Я хочу, чтобы получить ошибку во время компиляции/предупреждения, если я:

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

Насколько я могу судить, компилятор позволяет это, потому что они являются одним и тем же базовым типом.

ответ

4

Насколько я знаю, невозможно получить эту «безопасную типу», которую вы ищете для псевдонимов типов. Однако есть альтернатива псевдонимам типов, которые можно использовать для чего вы хотите: Value Classes. В принципе, класс значений может дать вам тип без выделения нового объекта. Обратите внимание, что существуют некоторые ограничения для классов значений, которые у вас нет для псевдонимов типов.

Процитирует документацию SCALA:

корректность

Другого примера использования классов стоимости, чтобы получить безопасность для типа данных без накладных расходов распределения времени выполнения. Например, фрагмент типа данных, который представляет собой расстояние может выглядеть следующим образом:

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

код, который добавляет два расстояния, такие как

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

не будет фактически выделяют любые экземпляры Meter, но будут использовать только примитивные двойники во время выполнения.

+0

Могу ли я создавать классы классов значений? Мне не нравится использование нового ключевого слова –

+0

Вы можете определить классы case. К слову: причина, по которой вы можете опустить «новое» ключевое слово, - это метод (apply) -компонента (сгенерированный) компаньона-объекта, поэтому вам необязательно определять класс case, чтобы избавиться от ключевого слова. –

+0

Да, я знаю, я просто предпочитаю не определять своих собеседников для всех псевдонимов типа, это длинный и скучный^_ ^ –

3

No. По крайней мере, не без изменения компилятора (это может возможно с плагин компилятора, или даже макро), и если вы сделали это изменение затем много популярных библиотек (включая стандарт библиотека), а стандартные примеры кода не будут компилироваться.

Возможно, вам понравятся классы значений, как описано в ответе @ Кулу. В качестве альтернативы Scalaz Tagged Types избегают накладных расходов в большем количестве ситуаций (например, помещая их в коллекцию или используя subst, чтобы безопасно повышать общий тип, который использует тегированный тип).

Смежные вопросы