正在 Iterable.sortedBy 内执行挂起函数
Executing suspend function inside Iterable.sortedBy
我有这个代码:
interface Film {
suspend fun total(): Int
}
suspend fun getFilms() : List<Film> {
return films.sortedBy { it.total() }
}
但是我得到一个错误,因为我在非暂停函数(sortedBy
选择器)中调用 Film::total
方法。我该如何解决?
我想这只是一个警告,无论如何你可以使用 runBlocking
强制它 运行
suspend fun getFilms() : List<Film> {
val films = arrayListOf<Film>()
return films.sortedBy { runBlocking { it.total() } }
}
suspend fun getFilms(): List<Film> {
return films
.map { it to it.total() }
.sortedBy { it.second }
.map { it.first }
}
错误说明得很清楚“暂停函数只能在协程体内调用”。您正在从 sortedBy 中调用 total() 因此出现错误。
您应该提供更多背景信息,以便我能够提供更准确的答案。有了这么少的上下文,您可以从 total() 中删除 suspend 让代码编译。无论如何,试试这个:
suspend fun getFilms() = films.sortedBy { it.total() }
如果您无法更改界面,那么类似的事情怎么办:
data class MyFilm(val total: Int) : Film {
override suspend fun total(): Int = total
}
suspend fun getFilms(): List<Film> = withContext(Dispatchers.Default) {
films.sortedBy { it.total }
}
如果你在多个地方使用它,你可以将@IR42 的答案包装在一个扩展函数中,使代码更具可读性。
suspend inline fun <T, R : Comparable<R>> Iterable<T>.sortedBySuspending(
crossinline selector: suspend (T) -> R?
): List<T> = this
.map { it to selector(it) }
.sortedBy { it.second }
.map { it.first }
我有这个代码:
interface Film {
suspend fun total(): Int
}
suspend fun getFilms() : List<Film> {
return films.sortedBy { it.total() }
}
但是我得到一个错误,因为我在非暂停函数(sortedBy
选择器)中调用 Film::total
方法。我该如何解决?
我想这只是一个警告,无论如何你可以使用 runBlocking
suspend fun getFilms() : List<Film> {
val films = arrayListOf<Film>()
return films.sortedBy { runBlocking { it.total() } }
}
suspend fun getFilms(): List<Film> {
return films
.map { it to it.total() }
.sortedBy { it.second }
.map { it.first }
}
错误说明得很清楚“暂停函数只能在协程体内调用”。您正在从 sortedBy 中调用 total() 因此出现错误。 您应该提供更多背景信息,以便我能够提供更准确的答案。有了这么少的上下文,您可以从 total() 中删除 suspend 让代码编译。无论如何,试试这个:
suspend fun getFilms() = films.sortedBy { it.total() }
如果您无法更改界面,那么类似的事情怎么办:
data class MyFilm(val total: Int) : Film {
override suspend fun total(): Int = total
}
suspend fun getFilms(): List<Film> = withContext(Dispatchers.Default) {
films.sortedBy { it.total }
}
如果你在多个地方使用它,你可以将@IR42 的答案包装在一个扩展函数中,使代码更具可读性。
suspend inline fun <T, R : Comparable<R>> Iterable<T>.sortedBySuspending(
crossinline selector: suspend (T) -> R?
): List<T> = this
.map { it to selector(it) }
.sortedBy { it.second }
.map { it.first }