Scala:如何使用函数返回的不可变值

时间:2013-03-19 13:50:12

标签: scala immutability

我是Scala的新手并尝试以功能方式使用它。以下是我的问题:

  1. 为什么我不能使用'< - '运算符为函数返回值创建'cnt'变量的新绑定?

  2. 如何以函数方式增加不可变变量(类似于Haskell&lt ;-)?为了实验,我不想使用可变的变量。

    import scala.io.Source
    object MyProgram {
    
      def main(args: Array[String]): Unit = {
        if (args.length > 0) {
          val lines = Source.fromFile(args(0)).getLines()
          val cnt = 0
          for (line <- lines) {
            cnt <- readLines(line, cnt)
          }
          Console.err.println("cnt = "+cnt)
        }
      }
    
      def readLines(line: String, cnt:Int):Int = {
        println(line.length + " " + line)
        val newCnt = cnt + 1
        return (newCnt)
      }
    }   
    
  3. 至于副作用,我永远不会指望(行&lt; - 行)是如此具有破坏性!它完全展开了行迭代器。因此,运行以下代码段将使size = 0:

    val lines = Source.fromFile(args(0)).getLines()
    var cnt = 0
    for (line <- lines) {
      cnt = readLines(line, cnt)
    }
    val size = lines.size
    

    像这样的隐藏副作用是否是正常的Scala练习?

3 个答案:

答案 0 :(得分:2)

你可以这样折叠lines

val lines = Source.fromFile(args(0)).getLines()
val cnt = lines.foldLeft(0) { case (count, line) => readLines(line, count) }
Console.err.println("cnt = "+cnt)

您的readLines方法会对println的调用产生副作用,但使用foldLeft可以保证从列表的从左到右处理,因此输出应该相同。

答案 1 :(得分:1)

为什么我不能使用'&lt; - '运算符将不可变'cnt'变量与函数返回值重新分配?

你为什么这样?如果您有java经验,&lt; - 在:中具有for(Item x: someCollection)的类似含义。 It is just a syntactic sugar用于从集合中获取当前项并命名它,它通常不是 bind 运算符。

此外,不是重新分配不可变 oxymoron

如何以函数方式增加不可变变量(类似于Haskell&lt; - )?

Scala人通常会使用.zipWithIndex,但只有当你要使用内部计数器进行理解时才会有效:

for((x, i) <- lines.zipWithIndex) { println("the counter value is" + i) } 

所以我认为您需要坚持lines.count或使用fold / reduce或=var指定新值。

答案 2 :(得分:0)

<-不是运算符,只是表达式中使用的语法。您必须使用=。如果要使用<-,它必须位于for-iteration-expression中。你不能增加val。如果要修改该变量,请将其设为var