【问题标题】:val evaluation while reading from stdio in scala从scala中的stdio读取时的val评估
【发布时间】:2016-07-03 13:47:48
【问题描述】:

这个程序从 std io 读取一些数字(每个数字都在新的一行)。我只输入一次数字! 现在,值“it”应该在定义点进行评估(而不是惰性 val),并且“it”应该被 RHS 的结果替换。

所以,当第一个 println(it.size) 被称为“it”时,它已经被计算过了。那么为什么第二次调用 prinln 总是返回零呢?似乎它尝试从 std io 再次读取,并且由于没有读取任何内容,因此它返回零。

object Test {
    def main(args: Array[String]) {
        val it= io.Source.stdin.getLines().map(_.toInt)
        println(it.size) // prints correct number of lines
        println(it.size) // prints zero always????   
    }
}

【问题讨论】:

    标签: scala stdin


    【解决方案1】:

    那为什么第二次调用prinln总是返回0

    因为Source.getLines 返回一个Iterator[String],您正在通过调用it.size 完全迭代它,这意味着迭代器到达了它的末尾。 This is how size is defined on TraversableOnce[A]Iterator[A] 扩展):

    def size: Int = {
      var result = 0
      for (x <- self) result += 1
        result
    }
    

    如果您希望能够进行多次迭代,则需要先实现迭代器:

    def main(args: Array[String]): Unit = {
      val it = io.Source.stdin.getLines().map(_.toInt).toSeq
      println(it.size)
      println(it.size)
    }
    

    请注意,这种实现会导致整个迭代器被加载到内存中。

    【讨论】:

    • 啊哈,所以 size 函数改变了迭代器的状态。我认为它只是返回一个整数并保持迭代器不变。谢谢:)
    猜你喜欢
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    相关资源
    最近更新 更多