正在 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 }