为什么scalac盒子Int?

St.*_*rio 4 int scala

我写了以下非常简单的测试:

import scala.collection.immutable.HashSet

class Test {
  def m() = {
    var s = new HashSet[Int]
    s = s + 1
  }
}
Run Code Online (Sandbox Code Playgroud)

并想通了它编译成这段代码:

public class Test {
  public void m();
    Code:
       0: new           #12                 // class scala/collection/immutable/HashSet
       3: dup
       4: invokespecial #15                 // Method scala/collection/immutable/HashSet."<init>":()V
       7: astore_1
       8: aload_1
       9: iconst_1
      10: invokestatic  #21                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
      13: invokevirtual #25                 // Method scala/collection/immutable/HashSet.$plus:(Ljava/lang/Object;)Lscala/collection/immutable/HashSet;
      16: astore_1
      17: return

  public Test();
    Code:
       0: aload_0
       1: invokespecial #30                 // Method java/lang/Object."<init>":()V
       4: return
}
Run Code Online (Sandbox Code Playgroud)

如您所见,1在使用1个元素创建新的不可变集之前,将其装箱.为什么装箱.Int extends AnyVal不是AnyRef.

And*_*kin 6

确切地说Int extends AnyVal,不是AnyRef.但是,immutable HashSet[A]具有Aas参数,它不是专用于原始类型的,也就是说,它不是@specialized(Int) A或者类似的东西,所以它只能处理扩展的引用类型,AnyRef原始类型必须被加框.幸运的是,Scala编译器隐藏了这一点.

  • @ St.Antario我认为主要是因为它会使编译的标准库的大小膨胀10倍(因为有9种原始类型,它们不是引用类型).在"Map [X,Y]"的情况下,它将是因子100x.但是,没有根本的限制,例如,据我记得,[paulp的非标准标准库](https://github.com/paulp/psp-std)可以普遍专注于所有事情,并且它有效(并且它比非专业版本工作得更快). (2认同)