如何将下述Scala代码中的var替换为val?
把Scala代码中的var替换为val的方案
嘿,很高兴帮你把这段命令式的Scala代码转换成纯不可变(用val)的实现!Scala推崇不可变变量,这样能减少可变状态带来的潜在bug,也更贴合函数式编程的风格。
先看看你的原代码:
var index: Long = lower var sum = 0L while(index <= upper) { if(number % index == 0L) sum += index index += 1L } sum
下面给你两种优雅的改造方案:
方案一:用Range+高阶函数(最简洁)
利用Scala的LongRange配合filter和sum方法,一行代码就能搞定,全程没有可变变量:
val sum = (lower to upper by 1L).filter(number % _ == 0L).sum
原理说明:
lower to upper by 1L:生成一个从lower到upper的不可变Long序列,步长为1filter(number % _ == 0L):筛选出所有能整除number的元素(这里的_是占位符,代表序列中的每个元素).sum:直接计算符合条件的元素总和,结果赋值给val sum
如果你觉得占位符不够清晰,也可以写成完整的lambda表达式:
val sum = (lower to upper by 1L).filter(index => number % index == 0L).sum
方案二:尾递归实现(纯函数式风格)
如果偏好更纯粹的函数式写法,可以用尾递归函数来模拟循环,所有状态都通过函数参数传递(函数参数默认是val):
def calculateSum(index: Long = lower, currentSum: Long = 0L): Long = { if (index > upper) currentSum else { val newSum = if (number % index == 0L) currentSum + index else currentSum calculateSum(index + 1L, newSum) } } val sum = calculateSum()
原理说明:
- 递归函数的参数
index和currentSum都是不可变的,每次递归调用都会传递新的数值 - Scala会自动对尾递归进行优化,转换成和while循环一样的性能,不用担心栈溢出问题
- 最终调用
calculateSum()就能得到结果,赋值给val sum
这两种方案都完全替换了原代码中的var,用val实现了相同的功能,而且代码更简洁、更易维护。
内容的提问来源于stack exchange,提问作者Anurag Beeram Naga
相关产品推荐
相关产品推荐

