kotlin实现Python Generator

本文探讨如何利用 Kotlin 的协程功能,实现类似 Python 中的 Generator,特别是支持传入初始参数的功能。通过这种方式,开发者可以在 Kotlin 中享受到类似于 Python 中的迭代器生成器的便利。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用kotlin协程实现Generator并支持传入初始参数

package leo.demo

import kotlin.coroutines.*

/**
 * 序列接口
 */
interface Generator<T> {
    operator fun iterator(): Iterator<T>
}

/**
 * 序列实现类
 */
class GeneratorImpl<T>
    (private val block: suspend GeneratorScope<T>.(T) -> Unit, private val parameter: T) :
    Generator<T> {
    override fun iterator(): Iterator<T> {
        return GeneratorIterator(block, parameter)
    }
}

/**
 * 序列状态机,表示是否准备好下一个值
 */
sealed class State {
    class NotReady(val continuation: Continuation<Unit>) : State()
    class Ready<T>(val continuation: Continuation<Unit>, val nextValue: T) : State()
    object Done : State()
}

/**
 * 序列迭代迭代器
 */
class GeneratorIterator<T>(private val block: suspend GeneratorScope<T>.(T) -> Unit, override val parameter: T) :
    GeneratorScope<T>(), Iterator<T>, Continuation<Any?> {
    override val context: CoroutineContext = EmptyCoroutineContext
    private var state: State

    init {
        //创建协程
        val coroutineBlock: suspend GeneratorScope<T>.() -> Unit = { block(parameter) }
        val star = coroutineBlock.createCoroutine(this, this)
        state = State.NotReady(star)
    }

    //挂起函数
    override suspend fun yield(value: T) = suspendCoroutine<Unit> { continuation: Continuation<Unit> ->
        state = when (state) {
            is State.NotReady -> State.Ready(continuation, value)
            is State.Ready<*> -> throw IllegalStateException("Cannot yield a value while ready")
            is State.Done -> throw java.lang.IllegalStateException("Cannot yield a value while done")
        }
    }

    //协程恢复
    private fun resume() {
        when (val currentState = state) {
            is State.NotReady -> currentState.continuation.resume(Unit)
        }
    }

    override fun hasNext(): Boolean {
        resume()
        return state != State.Done;
    }

    override fun next(): T {
        return when (val currentState = state) {
            is State.NotReady -> {
                resume()
                return next();
            }
            is State.Ready<*> -> {
                state = State.NotReady(currentState.continuation)
                (currentState as State.Ready<T>).nextValue
            }
            is State.Done -> throw IndexOutOfBoundsException("No value left")
        }
    }


    /**
     * 协程运行完毕后执行
     */
    override fun resumeWith(result: Result<Any?>) {
        state = State.Done
        result.getOrThrow();
    }
}

abstract class GeneratorScope<T> internal constructor() {
    protected abstract val parameter: T
    abstract suspend fun yield(value: T)
}

/**
 * 生成一个个序列生成器函数
 */
fun <T> generator(block: suspend GeneratorScope<T>.(T) -> Unit): (T) -> Generator<T> {
    return { parameter ->
        GeneratorImpl(block, parameter)
    }
}

fun main() {
    //生成一个个序列生成器函数
    val nums = generator<Int> { start ->
        for (i in 0..5) {
            yield(start + i)
        }
    }
    //幷成序列seq
    val seq = nums(10);

    //从序列获取值
    for (j in seq) {
        println("从seq获取值: $j")
    }
    // 官方提供了sequence
    val sequence=sequence{
        yield(1)
        yield(2)
        yieldAll(listOf(1,2,3,4))
    }
    for (x in sequence){
        println("x:$x")
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值