Scala for 循环内的赋值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6447631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Value assignment inside for-loop in Scala
提问by Felipe Hummel
Is there any difference between this code:
这段代码有什么区别:
for(term <- term_array) {
val list = hashmap.get(term)
...
}
and:
和:
for(term <- term_array; val list = hashmap.get(term)) {
...
}
Inside the loop I'm changing the hashmap with something like this
在循环内部,我正在用这样的东西更改哈希图
hashmap.put(term, string :: list)
While checking for the head of listit seems to be outdated somehow when using the second code snippet.
在list使用第二个代码片段时,检查它的头部似乎已经过时了。
采纳答案by rafalotufo
Instantiating variables inside for loops makes sense if you want to use that variable the forstatement, like:
如果您想在for语句中使用该变量,则在 for 循环中实例化变量是有意义的,例如:
for (i <- is; a = something; if (a)) {
...
}
And the reason why your list is outdated, is that this translates to a foreachcall, such as:
您的列表已过时的原因是,这会转化为foreach调用,例如:
term_array.foreach {
term => val list= hashmap.get(term)
} foreach {
...
}
So when you reach ..., your hashmap has already been changed. The other example translates to:
因此,当您到达...时,您的哈希图已经更改。另一个示例转换为:
term_array.foreach {
term => val list= hashmap.get(term)
...
}
回答by kiritsuku
The difference between the two is, that the first one is a definition which is created by pattern matching and the second one is a value inside a function literal. See Programming in Scala, Section 23.1 For Expressions:
两者之间的区别在于,第一个是通过模式匹配创建的定义,第二个是函数字面量内的值。有关表达式,请参阅Scala 编程,第 23.1 节:
for {
p <- persons // a generator
n = p.name // a definition
if (n startsWith "To") // a filter
} yield n
You see the real difference when you compile sources with scalac -Xprint:typer <filename>.scala:
当您使用以下命令编译源代码时,您会看到真正的区别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 }
}
After code transforming by the compiler you will get something like this:
编译器对代码进行转换后,您将得到如下结果:
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: (Int, Int)) => (x: (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]);
This can be simplified to:
这可以简化为:
val x1 = (1 to 5).map {i =>
val x: Int = i * 2
(i, x)
}.map {
case (i, x) => x
}
val x2 = (1 to 5).map {i =>
val x = i * 2
x
}

