android - Kotlin 中的 Nothing 子类是其他类的吗?

标签 android kotlin

以下代码 A 来自项目架构样本 https://github.com/android/architecture-samples

函数getTasks()将返回Result<List<Task>> .

类(class)data class Error(val exception: Exception)将返回Result<Nothing>() .

我认为代码Error(e)会导致错误,因为它无法返回 Result<List<Task>> .

Nothing 子类是 Kotlin 中任何其他类的子类吗?

代码A

class TasksLocalDataSource internal constructor(
    private val tasksDao: TasksDao,
    private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) : TasksDataSource {
    ...
   override suspend fun getTasks(): Result<List<Task>> {
        return withContext(ioDispatcher) {
            try {
                Success(tasksDao.getTasks())
            } catch (e: Exception) {
                Error(e)                   //I think that it will be cause error
            }
        }
    }
   ...
}


interface TasksDao {
  ...
  @Query("SELECT * FROM Tasks")
  suspend fun getTasks(): List<Task>
   ...
}

sealed class Result<out R> {

    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
    object Loading : Result<Nothing>()

    override fun toString(): String {
        return when (this) {
            is Success<*> -> "Success[data=$data]"
            is Error -> "Error[exception=$exception]"
            Loading -> "Loading"
        }
    }
}

最佳答案

通过“子”类,我假设您指的是类型?如果是这样,是Nothing确实是 Kotlin 中所有其他类型的子类型。它与Any?相反。它是 Kotlin 中每种类型的 super 类型。

Nothing是什么允许像 TODO() 这样的函数上类。该函数的实现是:

public inline fun TODO(): Nothing = throw NotImplementedError()

表明TODO() 从不返回任何内容,即它总是在运行时抛出异常。这就是允许 TODO()可以放置在任何上下文中。例如:

fun foo(): String = TODO()

编译时没有任何错误,即使 TODO()不返回String ,因为编译器知道 TODO()永远不会返回任何内容(更具体地说,NothingString 的子类型,因此“返回”该表达式中的有效类型)。

现在,回答你的问题:

I think the code Error(e) will cause error because it can't return Result<List<Task>>.

我们注意到Nothing 确实是所有其他类型的子类型。

我们还必须注意密封Result的定义类即 Result<out R>使用 variance annotation out 。这意味着类型参数 TResult始终仅从 Result返回 ,并且从未被 Result 消耗即Result协变于 T 。引用 Kotlin 文档:

The general rule is: when a type parameter T of a class C is declared out, it may occur only in out-position in the members of C, but in return C<Base> can safely be a supertype of C<Derived>.

将此规则与 Nothing 的知识相结合是所有其他类型的子类型,这允许 Error(e)它实现了 Result<Nothing>Result<List<Task>> 的有效返回值,因此您指示的代码行没有错误。

关于android - Kotlin 中的 Nothing 子类是其他类的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61300595/

相关文章:

java - 无法从三个 EditText 获取结果?

android - java.lang.IllegalArgumentException : Failed to find configured root that contains "insert app directory path here" 异常

reflection - java.lang.IllegalArgumentException : Callable expects 4 arguments, 但提供了 3 个

android - 使用自定义 BaseAdapter 刷新 GridView 内容

javascript - 如何查找仅移动设备和平板电脑支持的javascript属性?

java - Lint 检查不适用于 Java 但适用于 Android Studio 中的 Kotlin

kotlin - 如何在 kotlin 中对字符串数组进行排序

android - 现在必须显式声明 Kapt 注释处理器

android - 获取其他指针的 MotionEvent.getRawX/getRawY

intellij-idea - -Dkotlinx.coroutines.debug 在 IntelliJ IDEA JVM 选项中不起作用