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?
source to share
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
source to share
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.
source to share