1. 异常
如上图所示当我们使用 Result
类型时,IDE 会警告 ``kotlin.Resultcannot be used as a return type
。
// [ITmob.cn](https://itmob.cn) for more infomation.
fun main() {
println(testResult())
}
// Error: `kotlin.Result` cannot be used as a return type
private fun testResult(): Result<String> {
return Result.success("Result Test")
}
2. 原因
这是因为在 Kotlin 1.5 之前的版本中,Result<T>
类型的使用是有限制的。不能用作 Kotlin 函数的直接的返回值类型,这时 Result
类型和其属性也是受到限制的,它是未来版本可能支持的功能,还不能正式的使用。
如下是 Kotlin 1.5 之前 Result 类型的部分源码:
/**
* A discriminated union that encapsulates successful outcome with a value of type [T]
* or a failure with an arbitrary [Throwable] exception.
*/
@Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
@SinceKotlin("1.3")
public inline class Result<out T> @PublishedApi internal constructor(
@PublishedApi
internal val value: Any?
) : Serializable {
...
}
可以看到 Result 类型有一个特殊的注解:
@Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
将 Result 类型的构造函数标记为了未公开
3. 解决
如果仍然需要使用 Result
可以:
-
升级使用 Kotlin 1.5 或之后更高的版本
-
修改
Kotlin
编译器的参数绕过此限制如果坚持使用 Kotlin 1.5 之前的版本,也想尝试使用
Result
类型,可以修改编译器的参数Xallow-result-return-type
来绕过这个限制:- 如果你使用的构建语言是
Groovy
增加如下参数:
android { kotlinOptions { freeCompilerArgs = ["-Xallow-result-return-type"] } }
b. 如果你使用的构建语言是
Kotlin DSL
增加如下参数:android { kotlinOptions { freeCompilerArgs = listOf("-Xallow-result-return-type") } }
- 如果你使用的构建语言是
-
遵循 Kotlin 的限制条件使用
Kotlin 1.3 和 Kotlin 1.5 版本直接
Result
类型不能直接作为返回值的类型,但是在一些限制条件下还是可以使用的:- 可以作为泛型类型在容器中使用,或作为参数使用。
如:
fun findIntResults(): List<Result<Int>> // Ok fun receiveIntResult(result: Result<Int>) // Ok
- 返回类型为泛型类型的函数
如:
private val first: Result<Int> = findIntResults().first()
- 作为没有自定义 gettter 函数的私有属性
如:
private var foo: Result<Int> // Ok
关于
Result
类型在 Kotlin 1.5 之前的限制的详细介绍,可以参见文档:Limitations (legacy)
4. 其他
关于
Result
类型的详解和用法可以参见另一篇文章:Kotlin 中 Result 类型的详解和用法