scala - 迭代器上的Scala映射不会产生副作用

标签 scala map iterator

为什么会这样

scala> List(1,2,3,4).iterator.map((x: Int) => println(x))

不打印出来
1
2
3
4

尽管
List(1,2,3,4).map((x: Int) => println(x))
List(1,2,3,4).foreach((x: Int) => println(x))
List(1,2,3,4).iterator.foreach((x: Int) => println(x))

都做吗?

换句话说,为什么迭代器上的映射将类型T映射到Unit并具有无法显示这些副作用的副作用?

编辑:

另外,如果迭代器是惰性的,那么为什么随后的lazyMap调用实际上从头到尾实际上计算了新的迭代器(提供了完整的新迭代器)?
def lazyMap[T, U](coll: Iterable[T], f: T => U) = new Iterable[U] {
  def iterator = coll.iterator map f
}

scala> lazyMap(List(1,2,3,4), (x: Int) => x + 1)
res4: java.lang.Object with Iterable[Int] = (2, 3, 4, 5)

最佳答案

迭代器上的原因映射是惰性的,您需要严格一些:

scala> List(1,2,3,4).iterator.map((x: Int) => println(x))
res0: Iterator[Unit] = non-empty iterator

// nothing actually happened yet, just remember to do this printing things

scala> res0.toList
1
2
3
4
res1: List[Unit] = List((), (), (), ())

当您在迭代器上执行foreach时,很明显您正在产生副作用,因此懒惰是不希望的。我不会对 map 这么说。

UPD

至于您的编辑:这种行为的原因是,对语句结果隐式调用了toString,这反过来又严格了迭代器-自己尝试以下代码:
scala> { lazyMap(List(1,2,3,4), {(x: Int) => println(x); x + 1}); 1 }

而且您会看到永不调用f函数

关于scala - 迭代器上的Scala映射不会产生副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12631778/

相关文章:

rust - 如何使用特征实现迭代器

Scala/Spark 版本兼容性

scala - 如何通过 SBT 发布 Ivy 依赖项?

Scala代码使用java.util.NoSuchElementException : next on empty iterator崩溃

c++ - 在 map 中存储标准 map

map - 同步hadoop中的多个map reduce作业

java - 获取内存(RAM)上的 map 大小

c++ - 迭代器拼接列表后存储了错误的值

scala - akka 如何启动主任务并阻止它完成?

java - Java 中一个集合可以有多个迭代器吗?