Похоже, что это в соответствии с spec (в 4.1 Объявления и определения значений - слегка переформатирован для отображения в стеке):
Определения значений могутальтернативно иметь образец (§8.1) как левая сторона.Если p - это какой-то шаблон, отличный от простого имени или имени, за которым следуют двоеточие и тип, определение значения val p = e
расширяется следующим образом:
- Если шаблон
p
имеет ограничениепеременные x1, . . . , xn
, где n >= 1
: Здесь $x
- новое имя.
val $x = e match {case p => (x1, . . . , xn)}
val x1 = $x._1
. . .
val xn = $x._n
Таким образом, создание кортежа происходит на этапе синтаксического анализа.Таким образом, val (i, s) = (1, "s")
увеличивается в конце фазы синтаксического анализатора до:
private[this] val x$1 = scala.Tuple2(1, "s"): @scala.unchecked match {
case scala.Tuple2((i @ _), (s @ _)) => scala.Tuple2(i, s)
};
val i = x$1._1;
val s = x$1._2
Измеряя это в этом простом тесте на миллион итераций:
def foo: (Int, String) = (123, "123")
def bar: Unit = { val (i, s) = foo }
def bam: Unit = { val f = foo; val i = f._1; val s = f._2 }
приводит к
foo: Elapsed: 0.030
bar: Elapsed: 0.051
._1 ._2 access: Elapsed: 0.040
и с флагом -optimize:
foo: Elapsed: 0.027
bar: Elapsed: 0.049
._1 ._2 access: Elapsed: 0.029