Scala type safety and overhead (type vs class)

I have a graph where each vertex has both an ID (which never changes) and a label (which changes frequently). Both are long.

I am currently defining the following types:

type VertexId = Long
type VertexLabel = Long

      

However, I ran into an error today when I passed the VertexLabel to a function that was expecting a VertexId. This is like the type that the scala compiler should prevent.

I decided to do this instead:

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

      

But then there is the extra boxing and unboxing overhead and some extra memory usage.

Is there anyway to get the best of both worlds? Define both types as Longs in such a way that the compiler will prevent you from using one like the other?

+3


source to share


2 answers


Yes, you can use value classes:

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

      



see http://docs.scala-lang.org/overviews/core/value-classes.html

+9


source


Typical aliases are really just for clarity of code. When you declare type VertexId = Long

, you say that is VertexId

equivalent Long

. Then it is transitively VertexId

equivalent VertexLabel

. They are still under the Long

bottom, and this is how the compiler will see them after the deal.

So, no, I don't think you can completely get the best of both worlds here, because you require VertexId

and VertexLabel

should be of different types. A simple type alias cannot do this.



@ Correct answer: you can use value classes to create different types (most of the time) without actually instantiating at runtime. But pay attention to the caveats in the link.

+3


source







All Articles