Разница между ними заключается в том, что первое является определением, которое создается путем сопоставления с образцом, а второе - значением внутри литерала функции.См. Программирование в Scala, раздел 23.1. Для выражений :
for {
p <- persons // a generator
n = p.name // a definition
if (n startsWith "To") // a filter
} yield n
Реальная разница наблюдается при компиляции источников с scalac -Xprint:typer <filename>.scala
:
object X {
val x1 = for (i <- (1 to 5); x = i*2) yield x
val x2 = for (i <- (1 to 5)) yield { val x = i*2; x }
}
После кодапреобразовав компилятором, вы получите что-то вроде этого:
private[this] val x1: scala.collection.immutable.IndexedSeq[Int] =
scala.this.Predef.intWrapper(1).to(5).map[(Int, Int), scala.collection.immutable.IndexedSeq[(Int, Int)]](((i: Int) => {
val x: Int = i.*(2);
scala.Tuple2.apply[Int, Int](i, x)
}))(immutable.this.IndexedSeq.canBuildFrom[(Int, Int)]).map[Int, scala.collection.immutable.IndexedSeq[Int]]((
(x$1: (Int, Int)) => (x$1: (Int, Int) @unchecked) match {
case (_1: Int, _2: Int)(Int, Int)((i @ _), (x @ _)) => x
}))(immutable.this.IndexedSeq.canBuildFrom[Int]);
private[this] val x2: scala.collection.immutable.IndexedSeq[Int] =
scala.this.Predef.intWrapper(1).to(5).map[Int, scala.collection.immutable.IndexedSeq[Int]](((i: Int) => {
val x: Int = i.*(2);
x
}))(immutable.this.IndexedSeq.canBuildFrom[Int]);