You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求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变量。
额外的简洁可读性建议
  1. 参数命名更直观:把fold里的参数从acc、num改成accumulatedSum、currentNum,虽然稍长一点,但可读性大幅提升,不用猜参数含义。
  2. 避免非空断言:刚才的实现里用了filterNotNull(),如果图紧凑想合并步骤,也可以写成takeWhile { it != null }.fold(...) { acc, num -> acc + num!! },但num!!的非空断言会降低代码的安全性(虽然逻辑上是安全的),所以更推荐保留filterNotNull()的写法。
  3. 添加注释:给函数加上简单的文档注释,比如:
    /**
     * 读取用户输入的多行BigDecimal数值,累加直到输入空行或结束,返回总和
     */
    fun sumOfBigDecimals(): BigDecimal { ... }
    
    这样其他开发者一看就懂函数的用途和行为。

内容的提问来源于stack exchange,提问作者Kristopher Noronha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:29:38