寻求Kotlin惯用写法:无可变变量无循环实现标准输入求和
嘿,这就帮你把代码改成地道的Kotlin风格,彻底摆脱可变变量和循环,同时让代码更清爽好读!
优化后的惯用实现
我们可以借助Kotlin的序列(Sequence)和函数式操作来重构代码,完全符合不可变编程的理念:
fun sumOfBigDecimals(): BigDecimal { return generateSequence { readBigDecimal() } .takeWhile { it != null } .filterNotNull() .fold(BigDecimal.ZERO) { accumulatedSum, currentNum -> accumulatedSum + currentNum } } // 简化readBigDecimal的逻辑,更符合Kotlin惯用写法 fun readBigDecimal() = readLine()?.takeIf { it.isNotEmpty() }?.let { BigDecimal(it) }
代码解释
这里每一步的作用都很清晰:
generateSequence { readBigDecimal() }:生成一个无限序列,每次迭代都会读取一行输入并尝试转为BigDecimal(空行或读取失败会返回null)。takeWhile { it != null }:一旦读取到null,就停止序列的生成,相当于原来的循环终止条件。filterNotNull():过滤掉序列中的null值,只保留有效的BigDecimal实例,避免后续处理空值的麻烦。fold(BigDecimal.ZERO) { ... }:从初始值BigDecimal.ZERO开始,逐个累加序列里的每个数值,最终得到总和——这一步完全替代了原来的可变sum变量。
额外的简洁可读性建议
- 参数命名更直观:把fold里的参数从
acc、num改成accumulatedSum、currentNum,虽然稍长一点,但可读性大幅提升,不用猜参数含义。 - 避免非空断言:刚才的实现里用了
filterNotNull(),如果图紧凑想合并步骤,也可以写成takeWhile { it != null }.fold(...) { acc, num -> acc + num!! },但num!!的非空断言会降低代码的安全性(虽然逻辑上是安全的),所以更推荐保留filterNotNull()的写法。 - 添加注释:给函数加上简单的文档注释,比如:
这样其他开发者一看就懂函数的用途和行为。/** * 读取用户输入的多行BigDecimal数值,累加直到输入空行或结束,返回总和 */ fun sumOfBigDecimals(): BigDecimal { ... }
内容的提问来源于stack exchange,提问作者Kristopher Noronha
相关产品推荐
相关产品推荐

