Scala:在类型别名不匹配时强制执行编译错误

时间:2014-11-03 12:43:13

标签: scala settings type-alias

在分配共享相同基础类型的不同类型别名时,有没有办法获得编译时错误(或至少是警告)?

换句话说,我说有这段代码:

type Address = String
type City = String

def foo(x:Address) = ...

如果我这样做,我想得到编译时错误/警告:

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

据我所知,编译器允许它,因为它们是相同的底层类型。

2 个答案:

答案 0 :(得分:5)

据我所知,不可能得到这种"类型安全"你寻找类型别名。但是,还有一种替代方法可以根据需要使用别名: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实例,但只会在运行时使用原始双精度。

答案 1 :(得分:3)

没有。至少,不是没有修改编译器(可能可以使用编译器插件,甚至宏),如果你做了这个改变,那么很多流行的库(包括标准库)和标准代码示例无法编译。

您可能想要使用值类,如@ Kulu的回答中所述。或者,Scalaz Tagged Types可以避免在更多情况下的开销(例如,将它们放入集合中,或使用subst安全地向上转换使用标记类型的泛型类型。)