以下代码 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()
永远不会返回任何内容(更具体地说,Nothing
是 String
的子类型,因此“返回”该表达式中的有效类型)。
现在,回答你的问题:
I think the code
Error(e)
will cause error because it can't returnResult<List<Task>>
.
我们注意到Nothing
确实是所有其他类型的子类型。
我们还必须注意密封Result
的定义类即 Result<out R>
使用 variance annotation out
。这意味着类型参数 T
的Result
始终仅从 Result
返回 ,并且从未被 Result
消耗即Result
协变于 T
。引用 Kotlin 文档:
The general rule is: when a type parameter
T
of a classC
is declared out, it may occur only in out-position in the members ofC
, but in returnC<Base>
can safely be a supertype ofC<Derived>
.
将此规则与 Nothing
的知识相结合是所有其他类型的子类型,这允许 Error(e)
它实现了 Result<Nothing>
为 Result<List<Task>>
的有效返回值,因此您指示的代码行没有错误。
关于android - Kotlin 中的 Nothing 子类是其他类的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61300595/