专门集合中的 AnyVal 元素是否需要装箱?

Do AnyVal elements inside specialized collections need boxing?

假设我有一个自定义 class,它扩展 AnyVal 并在内部使用 Long

case class Instruction(underlying: Long) extends AnyVal

当我将 Instruction 添加到专用于 Long 的集合中时,Instruction 是否需要装箱?

(是否有专门用于 Long 的 Scala 集合?我需要一个索引序列。)

是的,它会被装箱。不幸的是,值 classes 在用作类型参数(泛型)或放入集合时失去了所有好处。当它们需要被视为任何其他类型而不是完全值class本身的类型时,它们被装箱总是

该限制的原因是为了保留 Scala 语言的良好语义,这样的代码必须有效:

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 _ => ...
}

专业化不会在这里改变任何东西,任何集合(专业的或非专业的)都可以传递到它被视为 Coll[Any]Coll[T] 的地方,其中关于 exact[= 的信息27=] 元素类型丢失。

如果您想要 IndexedSeq[Long] 的未装箱存储空间,我认为 scala.collection.mutable.WrappedArray.ofLong 是最接近的。它也有相应的构建器,scala.collection.mutable.ArrayBuilder.ofLong.

目前 Scala 不支持 @specialized 用于 集合

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:我认为这是由于Java不支持原始集合造成的,由于 Java 泛型绑定到 Object 类型,但 原始类型 不是从 Object.