在 Kotlin 中省略 return 类型会导致问题吗?

Will omitting a return type in Kotlin cause issues?

考虑下面的示例,我在通用数据的伴生对象中定义了两个通用函数 class:

data class CommonResponse<T>(
    var data: T? = null
) {
    companion object {
        // WITH return type
        fun <T> succeed1(): CommonResponse<T> = CommonResponse()
        // WITHOUT explicit return type
        fun <T> succeed2() = CommonResponse<T>()
    }
}

在给定的上下文中,两个函数将具有相同的 return 签名。我毫不怀疑它们都能正常工作,但仍然有一个问题让我感到困惑:

您要描述的是类型推断对您的函数的适用性,succeed2。对于 context:

Kotlin has a concept of type inference for compile-time type information, meaning some type information in the code may be omitted, to be inferred by the compiler. There are two kinds of type inference supported by Kotlin.

  • Local type inference, for inferring types of expressions locally, in statement/expression scope;
  • Function signature type inference, for inferring types of function return values and/or parameters.

类型推断适用于类型上下文包含足够的信息以供类型约束求解器导出预期类型的​​情况。因此,在 succeed2 的情况下,您的函数 return 值已提供足够的 function signature type inference,因此在这种情况下它真的无关紧要。

反对函数签名类型推断的论点

如果您试图控制函数的签名,那么您可以争辩说显式声明 return 类型会给您带来编译时错误。 示例:假设我们将不安全地(没有 IDE 的帮助)将两个函数重构为 return AnotherType<T>

data class AnotherType<T>(
    val foo: T
)

data class CommonResponse<T>(
    var data: T? = null
) {
    companion object {
        // THIS WILL FAIL
        fun <T> succeed1(): CommonResponse<T> = AnotherType()
        // THIS WILL SUCCEED
        fun <T> succeed2() = AnotherType<T>()
    }

}

succeed2 函数签名类型推断将解析为 AnotherType<T>。 (而 succeed1 将无法编译)

这叫做single-expression function

在常规函数(块体)中,我们必须声明return类型,否则它将是Unit;但是,对于 single-expression 函数,编译器会推断出 return 类型,并为推断出的类型和显式声明的类型生成相同的输出。

所以在技术上没有区别如果推断类型是您实际想要的类型。 (你也可以return一个ArrayList,声明类型为List,这是另一种情况)

但是,为了清楚起见,您可能更愿意明确声明 return 类型。


Kotlin 官方文档:

Single-expression functions When a function returns a single expression, the curly braces can be omitted and the body is specified after a = symbol:

fun double(x: Int): Int = x * 2

Explicitly declaring the return type is optional when this can be inferred by the compiler:

fun double(x: Int) = x * 2