ITmob-Ly
发布于 2022-12-25 / 174 阅读
0

Kotlin Exception - 'kotlin.Result' cannot be used as a return type

kotlin.Result cannot be used as a return type

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 可以:

  1. 升级使用 Kotlin 1.5 或之后更高的版本

  2. 修改 Kotlin 编译器的参数绕过此限制

    如果坚持使用 Kotlin 1.5 之前的版本,也想尝试使用 Result 类型,可以修改编译器的参数 Xallow-result-return-type 来绕过这个限制:

    1. 如果你使用的构建语言是 Groovy 增加如下参数:
    android {
        kotlinOptions {
            freeCompilerArgs = ["-Xallow-result-return-type"]
        }
    }
    

    b. 如果你使用的构建语言是 Kotlin DSL 增加如下参数:

    android {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xallow-result-return-type")
        }
    }
    
  3. 遵循 Kotlin 的限制条件使用

    Kotlin 1.3Kotlin 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 类型的详解和用法