谁能举出一个例子来说明它的意思?

当我阅读关于lambda函数的Kotlin docs时,有一个绿色的方框说:

默认情况下会推断没有接收器的函数类型,即使 变量通过对扩展函数的引用进行初始化.至 改变这一点,显式指定变量类型.

仅供参考,下面的代码位于绿色框的顶部,因此应该与其相关:

val repeatFun: String.(Int) -> String = { times -> this.repeat(times) }
val twoParameters: (String, Int) -> String = repeatFun // OK

fun runTransformation(f: (String, Int) -> String): String {
    return f("hello", 3)
}
val result = runTransformation(repeatFun) // OK

推荐答案

以下是简短的答案:

fun Int.makeHexString(): String = toString(radix = 16)
println(255.makeHexString())) // ✅ correct
val f = Int::makeHexString
println(255.f())) // ❌ compiler error!

为了进行更详细的说明,让我们从一个普通(非扩展)函数开始.假设我们有一个转换,它接受一个数字并返回String.

fun makeHexString(n: Int): String = n.toString(radix = 16)
println(makeHexString(255)) // ff

在Kotlin中,我们可以创建一个变量,该变量包含对此函数的引用.可以以与原始函数相同的方式调用该引用.

fun makeHexString(n: Int): String = n.toString(radix = 16)
val f = ::makeHexString
println(f(255)) // ff

变量f有一个类型,这是它所指向的函数的类型.在本例中,函数的类型为(Int) -> String,因为它接受类型为Int的参数并返回String.编译器已经自动推断出这个类型,因为我们没有指定它.

如果我们愿意,我们可以将原始函数重写为扩展函数.

fun Int.makeHexString(): String = toString(radix = 16)
val hex = 255.makeHexString()

行为是相同的,但我们现在调用函数的方式不同了.输入数字显示在接收器位置,而不是参数列表中.

如果我们使用稍微不同的语法,我们仍然可以引用扩展函数.

fun Int.makeHexString(): String = toString(radix = 16)
val f = Int::makeHexString
println(255.f())) // ❌ compiler error!

但请注意,我们can't调用引用的方式与调用原始函数的方式相同.上面的代码不能编译.

原因是Kotlin假设该函数的类型实际上仍然是(Int) -> String.这就是你在问题中引用的文件中描述的内容.

我们可以通过为函数指定显式类型来修复它.我们可以指定Int.() -> String而不是(Int) -> String,以指示输入应该在接收器位置,而不是在参数列表中.

fun Int.makeHexString(): String = toString(radix = 16)
val f: Int.() -> String = Int::makeHexString
println(255.f())

现在,我们可以调用函数引用作为扩展,就像我们可以调用原始函数一样.

Select 将一个函数转换为扩展函数是一种风格和人体工程学的 Select ,可以使该函数更易于实现或调用.但是,在使用lambdas和高阶函数时,能够将函数视为多态和可互换的函数通常很有用.接收器和参数之间的区别在这里只是表面上的,所以Kotlin Select 忽略它,除非您明确地说明.

Kotlin相关问答推荐

使用另一个对象的列表创建对象

编译后的JavaFX应用程序立即以静默方式崩溃

Kotlin:类型不匹配:推断的类型已运行,但应等待

在 map 中查找键与在 kotlin 中查找 firstOrNull

Kotlin .如何用从 1 到 90 的 5 个唯一数字填充列表中的每一行?

在 Compose 中使用 Text() 时如何获取文本的大小?

我们应该在 Effect 和 Either 之间 Select 哪个作为我们业务服务的返回类型?

如何从 kotlin 中的数据类访问 val?

比较 Kotlin 中的可比对象列表

Kotlin:泛型、反射以及类型 T 和 T:Any 之间的区别

kotlin-bom 库是做什么的?

Android 与 Kotlin - 如何使用 HttpUrlConnection

如何为kotlin异常生成SerialVersionId?

在Kotlin中为Android编写库会有开销吗?

Kotlin out-projected 类型禁止使用

Kotlin-将UTC转换为当地时间

查找是否在列表中找到具有特定属性值的元素

将字符串编码为Kotlin中的UTF-8

Android room DAO 接口不适用于继承

如何在 spring-boot Web 客户端中发送请求正文?