Kotlin Flow 的 Collect 是否只是内部 kotlinx.coroutines API?
Is Kotlin Flow's Collect is only internal kotlinx.coroutines API?
以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 中编译示例代码?
将 collect
替换为 collectLatest
。
答案是,不,collect
不仅是内部kotlinx.coroutinesAPI。错误消息具有误导性。
根据@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
添加以下导入:
import kotlinx.coroutines.flow.collect
对于版本 1.6.0-RC3
和更高版本:
@InternalCoroutinesApi
注释已从所有 collect()
函数中删除(参见 this PR)。
这意味着我们不会再看到错误,也不需要导入
import kotlinx.coroutines.flow.collect
因为(连同 another PR 的变化)我们现在可以直接使用 collect()
成员函数。
Api 在较新版本的 kotlinx 协同程序中发生了变化,而不是 collect 函数中的 lambda,它应该作为链中的最终调用。文档示例:
flow
.onEach { value -> process(value) }
.catch { e -> handleException(e) }
.collect() // trigger collection of the flow
以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 中编译示例代码?
将 collect
替换为 collectLatest
。
答案是,不,collect
不仅是内部kotlinx.coroutinesAPI。错误消息具有误导性。
根据@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
添加以下导入:
import kotlinx.coroutines.flow.collect
对于版本 1.6.0-RC3
和更高版本:
@InternalCoroutinesApi
注释已从所有 collect()
函数中删除(参见 this PR)。
这意味着我们不会再看到错误,也不需要导入
import kotlinx.coroutines.flow.collect
因为(连同 another PR 的变化)我们现在可以直接使用 collect()
成员函数。
Api 在较新版本的 kotlinx 协同程序中发生了变化,而不是 collect 函数中的 lambda,它应该作为链中的最终调用。文档示例:
flow
.onEach { value -> process(value) }
.catch { e -> handleException(e) }
.collect() // trigger collection of the flow