据我了解,如果您创建一个值类的数组,您实际上是在创建一个对象数组,而不是包装的原语。这背后的原因是什么?
来源:
class Wrapper(val underlying: Int) extends AnyVal
class Main {
val i: Int = 1
val w: Wrapper = new Wrapper(1)
val wrappers = Array[Wrapper](new Wrapper(1), new Wrapper(2))
val ints = Array[Int](1, 2)
}
javap输出:
public class Main {
public int i();
public int w();
public Wrapper[] wrappers(); // <----why can't this be int[] as well
public int[] ints();
public Main();
}
最佳答案
值类的约束之一是 x.isInstanceOf[ValueClass]
仍应正常工作。正确的意思是:透明地,程序员不必知道何时可以或不可以装箱值。
如果 Array[Meter]
在运行时表示为 Array[Int]
,则以下代码将无法按预期工作,因为数组中的整数实际上是米的信息丢失了。
class Meter(val value: Int) extends AnyVal
def centimeters[A](as: Array[A]) = as.collect{ case m: Meter => m.value * 100 }
请注意,如果您有
val m = new Meter(42); m.isInstanceOf[Meter]
则编译器知道 m
是 Meter
即使它在运行时是 Int
并且他可以将 isInstanceOf
调用内联到 true
。另请注意,这不适用于数组。如果您根据需要将数组中的值装箱,则必须创建一个新数组,这对程序员来说是不透明的,因为数组是可变的并且使用引用相等性。对于大型阵列的性能来说,这也将是一场灾难。
关于scala - 为什么将一组值类编译为一组对象?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59836935/