我不知道如何让下面的代码不可变:
def function123(str: String, mapVal: Map[String, String]) = {
var str1 = str
mapVal.keySet.foreach({x =>
str1 = str1.replaceAll(/*some pattern involving x*/, mapVal.get(x).get)})
str1
}
我怀疑我会使用 foldLeft
或带有参数累加器的嵌套方法,但这只是我的想法。
那我该怎么做呢?
最佳答案
向左折叠
这里有一个循环。
具有副作用的不可变循环版本是 foldLeft
,所有副作用都被下一个状态创建所取代:
val result = mapVal.foldLeft(str){case (state, (key, value)) =>
state.replaceAll(/*some pattern involving key*/, value)
}
要在不可变环境中工作,循环的每次迭代都应返回值并将前一次迭代的结果作为参数。这正是 foldLeft
的作用。
递归
另一种解决方案是递归方法。您应该将循环迭代提取到方法中,并使该方法最后调用下一次迭代:
def function123(str: String, mapVal: Map[String, String]) = {
@tailrec def loop(state: String, pairs: List[(String, String)]): String = pairs match {
case Nil => state
case (key, value) :: tail =>
val nextState = state.replaceAll(/*some pattern involving key*/, value)
loop(nextState, tail)
}
loop(str, mapVal.toList)
}
可变循环 -> 不可变
要使具有可变循环的代码成为不可变的,您应该将循环内更改中隐式涉及的所有值提取到某种状态(foldLeft
的单个状态对象或递归方法的一堆参数)然后在每次迭代结束时基于先前的状态产生一个新的状态。
关于scala - 使代码的和平不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17312271/