Do AnyVal elements inside specialized collections need boxing?

324 views Asked by At

Say I have a custom class which extends AnyVal and uses a Long internally:

case class Instruction(underlying: Long) extends AnyVal

When I add Instructions to a collection which is specialized for Long, do the Instructions need boxing?

(Are there Scala collections which are specialized for Long? I need an indexed sequence.)

2

There are 2 answers

0
ghik On BEST ANSWER

Yes, it will be boxed. Unfortunately, value classes lose all their benefits when used as type arguments (generics) or put into collections. They are boxed always when they need to be seen as any other type than exactly the type of the value class itself.

The reason for that limitation is that to retain sound semantics of Scala language, code like this must work:

case class ValueClass(raw: Long) extends AnyVal
val someList: List[Any] = List[ValueClass](ValueClass(42L))
someList.head match {
  case ValueClass(raw) => // boxing needed for this match to work...
  case _ => ...
}

Specialization doesn't change anything here, any collection (specialized or not) could be passed somewhere where it's seen as Coll[Any] or Coll[T] where information about exact element type is lost.

If you want an IndexedSeq[Long] with unboxed storage, I think scala.collection.mutable.WrappedArray.ofLong is the closest thing to that. It also has its corresponding builder, scala.collection.mutable.ArrayBuilder.ofLong.

0
chengpohi On

For now Scala doesn't support @specialized for collection.

Currently there is no support for specialization of collections. It would be nice to allow this in the new design if we can do it without too much of an impact on the majority of non-specialized collections.

https://www.scala-lang.org/blog/2017/02/28/collections-rework.html

PS: I think this is caused by the Java doesn't support primitive collection, Since Java generiction is bound to the Object type, but primitive type doesn't derive from Object.