理解Kotlin';s屈服函数

理解Kotlin';s屈服函数,kotlin,yield,kotlin-android-extensions,kotlin-coroutines,Kotlin,Yield,Kotlin Android Extensions,Kotlin Coroutines,我在Kotlin中看不到函数的非常清晰的定义 上面链接中的示例并没有提到太多,但提到了以下内容: val sequence = sequence { val start = 0 // yielding a single value yield(start) // yielding an iterable yieldAll(1..5 step 2) // yielding an infinite sequence yieldAll(gener

我在Kotlin中看不到函数的非常清晰的定义

上面链接中的示例并没有提到太多,但提到了以下内容:

val sequence = sequence {
    val start = 0
    // yielding a single value
    yield(start)
    // yielding an iterable
    yieldAll(1..5 step 2)
    // yielding an infinite sequence
    yieldAll(generateSequence(8) { it * 3 })
}

println(sequence.take(7).toList()) // [0, 1, 3, 5, 8, 24, 72]
但上面的例子并没有指出收益率的重要性

  • 它是一个暂停函数,这意味着什么
  • 在什么情况下,这是有利的

让我们考虑一个例子,在这里您可以生成序列的下一个元素,但是您没有看到实现java迭代器的简单方法。p>


fun fibonacci() = sequence {
  var a_0 = 1
  var a_1 = 1

  // this sequence is infinite
  while(true) {
    val a_n = a_0 + a_1
    a_0 = a_1
    a_1 = a_n

    //this is a suspend function call
    yield(a_0)
  }
}
该示例使用
yield
函数返回序列的下一个元素。该函数是Kotlin中的
suspend
函数的一个示例。对函数的调用暂停执行
sequence{..}
块,因此调用堆栈是自由的

假设我们执行以下操作

fibonacci().take(10).forEach{ 
   println(it) 
}
forEach
循环的每次迭代都将从上一次
yield
函数调用恢复
sequence{..}
块,并让它运行到下一次
yield
函数调用。执行流将把
forEach
循环迭代与
sequence{..}
块计算混合在一起。您可以尝试编写与Java
迭代器相同的代码,以了解Kotlin编译器在幕后的工作

suspend
Kotlin中的函数在语言和标准库端以最低限度的方式完成,其余的可以在库中实现。我建议查看
kotlinx.coroutines
库以了解更多内部信息、示例和文档

您可以将
yield()
想象为“返回,下次从您停止的地方开始”:

它创建了状态机之类的东西,但您可以在Java中将其转换为类似的东西:

class Seq {
    private AtomicInteger count = new AtomicInteger(0);
    private int state = 0;

    public int nextValue() {
        if (count.get() == 0) {
           return state;
        }
        else if (count.get() >= 1 && count.get() <= 5) {
           state += 2;
           return state;
        }
        else {
           state *= 3;
           return state;
        }
    }
}
class-Seq{
私有AtomicInteger计数=新的AtomicInteger(0);
私有int状态=0;
public int nextValue(){
if(count.get()==0){
返回状态;
}

否则,如果(count.get()>=1&&count.get(),那么再次调用该方法是否正确?例如,Java中的foreach(..){fibonacci(10)}?是的,
.foreach{..}
是内联函数,在Java字节码级别,它将类似于Java的foreachs。这与协同程序有关吗?我认为您应该增加每次调用的计数。
class Seq {
    private AtomicInteger count = new AtomicInteger(0);
    private int state = 0;

    public int nextValue() {
        if (count.get() == 0) {
           return state;
        }
        else if (count.get() >= 1 && count.get() <= 5) {
           state += 2;
           return state;
        }
        else {
           state *= 3;
           return state;
        }
    }
}