我是Scala的新手并尝试以功能方式使用它。以下是我的问题:
为什么我不能使用'< - '运算符为函数返回值创建'cnt'变量的新绑定?
如何以函数方式增加不可变变量(类似于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)
}
}
至于副作用,我永远不会指望(行&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练习?
答案 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
。