Bla*_*jac 8 scala tuples iterable-unpacking
为什么这个Scala代码:
class Test
{
def foo: (Int, String) =
{
(123, "123")
}
def bar: Unit =
{
val (i, s) = foo
}
}
Run Code Online (Sandbox Code Playgroud)
生成以下字节码bar(),构造一个新的Tuple2,将Tuple2from 传递foo()给它,然后从中获取值?
public void bar();
Code:
0: aload_0
1: invokevirtual #28; //Method foo:()Lscala/Tuple2;
4: astore_2
5: aload_2
6: ifnull 40
9: new #7; //class scala/Tuple2
12: dup
13: aload_2
14: invokevirtual #32; //Method scala/Tuple2._1:()Ljava/lang/Object;
17: aload_2
18: invokevirtual #35; //Method scala/Tuple2._2:()Ljava/lang/Object;
21: invokespecial #20; //Method scala/Tuple2."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
24: astore_1
25: aload_1
26: invokevirtual #39; //Method scala/Tuple2._1$mcI$sp:()I
29: istore_3
30: aload_1
31: invokevirtual #35; //Method scala/Tuple2._2:()Ljava/lang/Object;
34: checkcast #41; //class java/lang/String
37: astore 4
Run Code Online (Sandbox Code Playgroud)
这是因为编译器没有检查foo()s返回值不是元组吗?
JVM是否会优化构造?
这似乎符合规范(在4.1 值声明和定义中- 为 stackoverflow 显示稍微重新格式化):
\n\n\n\n\n值定义也可以将模式 (\xc2\xa78.1) 作为左侧。如果 p 是除简单名称或名称后跟冒号和类型之外的某种模式,则值定义
\n\nval p = e将扩展如下:\n
\n- 如果模式
\np具有绑定变量x1, . . . , xn,其中n >= 1:\n 这里$x是一个新名称。
val $x = e match {case p => (x1, . . . , xn)}\n val x1 = $x._1\n . . .\n val xn = $x._n\nRun Code Online (Sandbox Code Playgroud)\n\n因此元组的创建发生在解析器阶段。因此val (i, s) = (1, "s")在解析器阶段结束时花费:
private[this] val x$1 = scala.Tuple2(1, "s"): @scala.unchecked match { \n case scala.Tuple2((i @ _), (s @ _)) => scala.Tuple2(i, s)\n};\nval i = x$1._1;\nval s = x$1._2\nRun Code Online (Sandbox Code Playgroud)\n\n通过一百万次迭代的简单测试来测量这一点:
\n\ndef foo: (Int, String) = (123, "123")\ndef bar: Unit = { val (i, s) = foo }\ndef bam: Unit = { val f = foo; val i = f._1; val s = f._2 }\nRun Code Online (Sandbox Code Playgroud)\n\n产量
\n\nfoo: Elapsed: 0.030\nbar: Elapsed: 0.051\n._1 ._2 access: Elapsed: 0.040\nRun Code Online (Sandbox Code Playgroud)\n\n并带有 -optimize 标志:
\n\nfoo: Elapsed: 0.027\nbar: Elapsed: 0.049\n._1 ._2 access: Elapsed: 0.029\nRun Code Online (Sandbox Code Playgroud)\n