Scala类型 - 安全性与开销(类型与类)

时间:2015-05-14 20:21:33

标签: scala types type-safety

我有一个图表,其中每个顶点都有一个ID(永远不会改变)和一个标签(经常变化)。两者都以长子为代表。

目前,我定义了以下类型:

type VertexId = Long
type VertexLabel = Long

但是,我今天发现了一个错误,我将VertexLabel传递给了一个期望VertexId的函数。这似乎是scala编译器应该能够阻止的类型。

我考虑过这样做:

case class VertexId(id: Long)
case class VertexLabel(label: Long)

但随后还有#34;拳击"和#34;拆箱"和一些额外的内存使用。

无论如何都要充分利用这两个世界?将这两种类型定义为Longs,以便编译器阻止您使用另一种?

2 个答案:

答案 0 :(得分:9)

是的,您可以使用值类:

case class VertexId(val id: Long) extends AnyVal
case class VertexLabel(val label: Long) extends AnyVal

请参阅http://docs.scala-lang.org/overviews/core/value-classes.html

答案 1 :(得分:3)

类型别名实际上仅用于代码清晰度。当您声明type VertexId = Long时,您说VertexId 等效Long。然后,VertexId相当于VertexLabel。它们仍然是Long下面的,这就是编译器在消除锯齿后会看到它们的方式。

所以不,我不认为你可以完全在这里获得两全其美,因为你的要求是VertexIdVertexLabel必须是不同的类型。简单类型别名不能这样做。

@ Lee的答案是正确的,因为您可以使用值类创建不同的类型(大多数时候),而无需在运行时实际实例化类型。但请注意链接中的警告。