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
相关产品推荐
相关产品推荐

