gpt4 book ai didi

scala - 为什么将值类数组编译为对象数组?

转载 作者:行者123 更新时间:2023-12-01 08:43:37 25 4
gpt4 key购买 nike

据我了解,如果您创建一个值类的数组,您实际上是在创建一个对象数组,而不是包装的原语。这背后的原因是什么?

来源:

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],则以下代码将无法按预期工作,因为 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com