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

如何为OpenEndRange<LocalDate>实现map等高阶函数?

为OpenEndRange实现高阶函数支持

你的代码核心问题有两个:迭代器的hasNext()逻辑错误,以及可能未正确导入自定义的rangeUntil运算符导致使用了标准库的非Iterable实现。以下是修正方案:

1. 修复迭代器判断逻辑

你当前的hasNext()判断currentDate.plusDays(stepDays) <= endExclusive,会漏掉那些当前日期仍在开区间内,但加上步长后超出范围的元素。正确判断应直接检查当前日期是否小于结束日期(符合开区间start ≤ x < endExclusive的核心规则)。

2. 简化迭代器实现(可选)

用Kotlin标准库的generateSequence替代自定义迭代器类,代码更简洁且不易出错。

修正后的完整代码

package de.otto.di.extensions

import java.time.LocalDate

@OptIn(ExperimentalStdlibApi::class)
class OpenEndLocalDateRange(
    override val start: LocalDate,
    override val endExclusive: LocalDate,
    private val stepDays: Long = 1
) : Iterable<LocalDate>, OpenEndRange<LocalDate> {

    override fun iterator(): Iterator<LocalDate> = generateSequence(start) { it.plusDays(stepDays) }
        .takeWhile { it < endExclusive }
        .iterator()

    infix fun step(days: Long): OpenEndLocalDateRange = OpenEndLocalDateRange(start, endExclusive, days)
}

infix operator fun LocalDate.rangeUntil(to: LocalDate): OpenEndLocalDateRange =
    OpenEndLocalDateRange(this, to)

使用注意事项

在需要使用该开区间的代码文件中,必须导入自定义扩展函数:

import de.otto.di.extensions.rangeUntil

否则会默认使用Kotlin标准库为LocalDate生成的OpenEndRange实现(该实现不继承Iterable,无法使用map、forEach等高阶函数)。

测试示例

import de.otto.di.extensions.rangeUntil
import java.time.LocalDate

fun main() {
    val from = LocalDate.now().minusDays(10)
    val to = LocalDate.now()
    
    // 直接遍历
    (from ..< to).forEach { println(it) }
    
    // 使用map转换
    val nextDays = (from ..< to).step(2).map { it.plusDays(1) }
    println(nextDays)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:45:33