以下两个陈述之间是否有任何区别?他们达到了同样的目的,对吗?他们编译成相同的Java代码吗?它们之间是否存在性能差异,还是只是偏好/可读性问题?
for (thing <- things) {
doSome(thing)
}
things.foreach(
thing =>
doSome(thing)
)
答案 0 :(得分:15)
他们是完全相同的。给定
class Foreach {
val things = List(1,2,3)
def doSome(i: Int) { println(i) }
def one { for (thing <- things) { doSome(thing) } }
def two { things.foreach{ thing => doSome(thing) } }
}
字节码是
public void one();
Code:
0: aload_0
1: invokevirtual #40; //Method things:()Lscala/collection/immutable/List;
4: new #42; //class Foreach$$anonfun$one$1
7: dup
8: aload_0
9: invokespecial #46; //Method Foreach$$anonfun$one$1."<init>":(LForeach;)V
12: invokevirtual #52; //Method scala/collection/immutable/List.foreach:(Lscala/Function1;)V
15: return
public void two();
Code:
0: aload_0
1: invokevirtual #40; //Method things:()Lscala/collection/immutable/List;
4: new #55; //class Foreach$$anonfun$two$1
7: dup
8: aload_0
9: invokespecial #56; //Method Foreach$$anonfun$two$1."<init>":(LForeach;)V
12: invokevirtual #52; //Method scala/collection/immutable/List.foreach:(Lscala/Function1;)V
15: return
答案 1 :(得分:10)
for
理解被定义为简单的句法翻译。这非常重要,因为它允许任何对象使用for
理解,它只需要实现正确的方法。
IOW:Scala语言规范说第一个片段被翻译成第二个片段。因此,如果两个片段之间存在任何差异,那将违反规范,因此是一个非常严重的编译器错误。
有些人已经要求甚至实施某些对象的特殊处理(例如Range
s),但这些补丁总是被拒绝,因为特殊类型的特殊处理只会使那些特殊类型受益,而使Scala更快一般将使每个人受益。
请注意,对于宏,它可能会检测,例如,Range
上的迭代纯粹作为简单的C样式for
循环,并将其转换为while
循环或直接的tailrecursive内部函数,无需更改规范或向编译器添加特殊外壳。
答案 2 :(得分:1)
与往常一样,for-expressions可以用作涉及foreach,map,withFilter和flatMap的表达式的替代语法,因此打印迭代器返回的所有元素的另一种方法是:
for(elem&lt; - it)println(elem)
“替代语法”意思相同。
答案 3 :(得分:-1)
基本上
for
循环是一个结构
执行此操作。次
foreach
循环是一个结构
针对每个值/对象执行此操作