代码之家  ›  专栏  ›  技术社区  ›  david.perez

Scala中的迭代与Kotlin

  •  2
  • david.perez  · 技术社区  · 2 年前

    我正在将一些代码从Scala迁移到Kotlin,我观察到了不同的行为:

    Scala:

    var i = 0
    
    Iterator.continually{
      println(s"i=$i")
      i += 1
      i
    }.takeWhile { 
      _ < 3
    }.foreach { i =>
      println(s"I=$i")
    }
    

    输出:

    
    Console (F3)
    
    i=0
    I=1
    i=1
    I=2
    i=2
    

    Kotlin等效物:

    fun <A> continousIterator(func: () -> A): Iterable<A> =
        object: Iterable<A> {
            override fun iterator() =
                object: Iterator<A> {
                    override fun hasNext(): Boolean = true
                    override fun next(): A = func()
                }
        }
        
    var i = 0;
        
    fun main() {
        continousIterator{
            println("i=$i")
            i += 1
            i
        }.takeWhile{
          it < 3
        }.forEach { 
          println("I=$it")
        }
    }
    

    输出:

    i=0
    i=1
    i=2
    I=1
    I=2
    

    当我们有state时,结果不一样,的调用顺序 func() 以及 iterator 不同。

    我想知道为什么。

    1 回复  |  直到 2 年前
        1
  •  2
  •   Gaël J    2 年前

    在科特林,当 takeWhile 被称为, takeWhile 立即迭代序列并打印0到2,并生成 List 。只有在那之后 forEach 开始跑步,打印1和2。

    要复制Scala的行为,您需要 对于每个 使用序列,而不是 takeWhile a. Sequence 可以做到这一点:

    generateSequence {
        println("i=$i")
        i += 1
        i
    }.takeWhile{it < 3}.forEach { println("I=$it")}
    

    对的操作 序列 他们都很懒惰。除非绝对必要,否则他们不会消耗序列。

    推荐文章