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

Kotlin Koans运算符重载代码本地正常为何无法通过测试?

为什么我的Kotlin运算符重载代码能正常运行但通不过Kotlin Koans测试?

我写了下面的Kotlin代码,在独立项目里运行符合预期,但提交到Kotlin Koans的运算符重载测试时却无法通过,请问问题出在哪?

import TimeInterval.*

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

// Supported intervals that might be added to dates:
enum class TimeInterval(var n: Int = 1) {
    DAY, WEEK, YEAR
}

operator fun TimeInterval.times(times: Int): TimeInterval {
    n *= times
    return this
}

operator fun MyDate.plus(timeInterval: TimeInterval): MyDate =
    addTimeIntervals(timeInterval, timeInterval.n)

问题原因

核心问题出在枚举的单例特性上:

  • TimeInterval是枚举类,它的每个实例(DAY/WEEK/YEAR)都是全局唯一的单例。
  • 你在times函数里直接修改了枚举实例的n属性,这会永久改变该枚举的全局状态。比如第一次调用DAY * 3后,后续所有使用DAY的地方,它的n值都会是3而非默认的1。
  • 你的独立测试可能只执行了一次操作,所以看不出问题,但Kotlin Koans的测试用例会多次验证不同场景(比如先测试DAY*3,再测试单独的DAY),此时被修改的枚举状态会导致后续断言失败。

修正方案

不要修改枚举的内部状态,而是通过一个包装类来传递「时间间隔+重复次数」的组合,避免污染全局枚举实例:

import TimeInterval.*

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

enum class TimeInterval {
    DAY, WEEK, YEAR
}

// 新增包装类,存储间隔类型和重复次数
data class RepeatedTimeInterval(val interval: TimeInterval, val count: Int)

// 重载times运算符,返回包装类而非修改枚举
operator fun TimeInterval.times(times: Int): RepeatedTimeInterval {
    return RepeatedTimeInterval(this, times)
}

// 支持直接添加单个时间间隔
operator fun MyDate.plus(timeInterval: TimeInterval): MyDate =
    addTimeIntervals(timeInterval, 1)

// 支持添加重复的时间间隔
operator fun MyDate.plus(repeated: RepeatedTimeInterval): MyDate =
    addTimeIntervals(repeated.interval, repeated.count)

这个方案中,每次调用DAY * 3都会生成一个独立的RepeatedTimeInterval实例,不会影响原始的DAY枚举状态,完全符合Koans测试的预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:05:13