45

https://kotlinlang.org/docs/reference/coroutines/flow.html#flows-are-cold的直接示例

fun simple(): Flow<Int> = flow { 
    println("Flow started")
    for (i in 1..3) {
        delay(100)
        emit(i)
    }
}

fun main() = runBlocking<Unit> {
    println("Calling simple function...")
    val flow = simple()
    println("Calling collect...")
    flow.collect { value -> println(value) } 
    println("Calling collect again...")
    flow.collect { value -> println(value) } 
}

我得到了错误collect

This is an internal kotlinx.coroutines API that should not be used from outside of kotlinx.coroutines. No compatibility guarantees are provided.It is recommended to report your use-case of internal API to kotlinx.coroutines issue tracker, so stable API could be provided instead

当我添加@InternalCoroutinesApi

@InternalCoroutinesApi
fun main() = runBlocking<Unit> {
    println("Calling simple function...")
    val flow = simple()
    println("Calling collect...")
    flow.collect { value -> println(value) }
    println("Calling collect again...")
    flow.collect { value -> println(value) }
}

collect我在的 lambda(的函数)中得到一个错误,value -> println(value如下所示

Type mismatch.
Required:
FlowCollector<Int>
Found:
([ERROR :  ]) → Unit
Cannot infer a type for this parameter. Please specify it explicitly.

我正在使用 Kotlin 版本 1.4.21。

    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.2"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
    testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'

我做错了什么无法在 Android Studio 中编译示例代码吗?

4

4 回答 4

82

答案是,NO,collect不仅仅是内部的 kotlinx.coroutines API。错误消息具有误导性。

根据@ir42 的评论,add import kotlinx.coroutines.flow.collect 解决问题。

附加信息,为什么我没有选择collectLatest作为答案

collect并且collectLatest是不同的。

使用这个例子

fun simple(): Flow<Int> = flow { // flow builder
    for (i in 1..3) {
        delay(100) // pretend we are doing something useful here
        emit(i) // emit next value
    }
}

fun main() = runBlocking<Unit> {
    // Launch a concurrent coroutine to check if the main thread is blocked
    launch {
        for (k in 1..3) {
            println("I'm not blocked $k")
            delay(100)
        }
    }
    // Collect the flow
    simple().collect { value -> println(value) } 
}

收集将产生

I'm not blocked 1
1
I'm not blocked 2
2
I'm not blocked 3
3

根据https://kotlinlang.org/docs/reference/coroutines/flow.html

collectLatest

fun simple(): Flow<Int> = flow { // flow builder
    for (i in 1..3) {
        delay(100) // pretend we are doing something useful here
        emit(i) // emit next value
    }
}

fun main() = runBlocking<Unit> {
    // Launch a concurrent coroutine to check if the main thread is blocked
    launch {
        for (k in 1..3) {
            println("I'm not blocked $k")
            delay(100)
        }
    }
    // Collect the flow
    simple().collectLatest { value -> println(value) } 
}

会产生

I'm not blocked 1
I'm not blocked 2
1
I'm not blocked 3
2
于 2021-01-04T09:07:14.003 回答
7

添加以下导入:

import kotlinx.coroutines.flow.collect
于 2021-11-18T20:37:20.880 回答
1

对于版本1.6.0-RC3和更新:

@InternalCoroutinesApi注释已从所有collect()函数中删除(请参阅此PR)。

这意味着我们不会再看到错误,也不需要导入

import kotlinx.coroutines.flow.collect

不再是因为(连同另一个 PR的更改)我们现在可以collect()直接使用成员函数。

于 2021-12-17T18:58:27.780 回答
-1

替换collectcollectLatest

于 2021-01-04T07:40:04.580 回答