kotlin - 当接收者从上下文中获知时,缩短对类方法的引用

标签 kotlin type-inference method-reference

在以下代码中,

class IncWrapper<T> (val wrapped: T, val base: Int) {
    fun incFunction(increment: Int, func: T.(Int) -> Int): Int {
        return increment + wrapped.func(base)
    }
}

class ClassWithIndecentlyLongName {
    fun square(x: Int) = x * x
}

fun main() {
    val wrapper = IncWrapper(ClassWithIndecentlyLongName(), 2)
    val computed = wrapper.incFunction(1, ClassWithIndecentlyLongName::square)
    println(computed)
}

我们传递对包装类的方法的引用 ClassWithIndecentlyLongName .由于在调用站点知道该类应作为该方法的接收者,因此再次传递该类的名称似乎很尴尬/多余。我希望类似 ::square工作,但它没有。如果缺少这样的功能,可能是什么原因?

(问题源于试图重构一些非常冗长的 Java 代码,将一个类的大量字段转换为另一个。)

最佳答案

仅使用 ::square这意味着,它是您的包或从中调用它的文件/类的一部分。但在这种情况下这是不正确的。

如果你有这么长的名字,你可以从函数引用切换到实际的 lambda,例如:

wrapper.incFunction(1) { square(it) }

如果您有更多参数,那么类型别名可能更有用,例如
typealias Functions = ClassWithIndecentlyLongName // choose a name that's more appropriate

// and calling it as follows:
wrapper.incFunction(1, Functions::square)

或者使用别名导入该类,例如:
import ClassWithIndecentlyLongName as ShortName

但是,更好的方法可能是丢弃不雅的长名称并用更合适的名称代替它。

最后,如果你真的只想使用 ::square如果您提供所需的包装函数,您仍然可以这样做,例如:
fun square(c : ClassWithIndecentlyLongName, i : Int) = c.square(i)

// calling it, now works as you wanted:
wrapper.incFunction(1, ::square)

现在:为什么会这样?我只能猜测。但对我来说很有意义,您需要准确指定可以找到该函数的位置。我认为,如果您永远无法确定哪个函数恰好在指定的函数后面,那么它反而会使代码复杂化。

关于kotlin - 当接收者从上下文中获知时,缩短对类方法的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57919317/

相关文章:

android - 无法解析编译器类路径。检查项目 ':app' 中是否配置了 Kotlin Gradle 插件存储库

java - "Return type of ... is not a subtype of the return type of the overridden member"?

android - Android Studio 3.0 canary 2 中带有 Android DataBinding 的 Kotlin

Kotlin 对 "supposedly"正确类型的类型推断

Java 8 链式方法引用?

java - 如何将具有动态值的 lambda 过滤器转换为方法引用

kotlin - Kotlin中Java8时间对比

f# - 记录类型推断

typescript - 为什么从any[] 的元组推断会变成[string, string, ... ],而从string[] 的元组推断会变成['literal1' , 'literal2' , ... ]

java - 为什么 'T.super.toString()' 和 'super::toString' 使用合成访问器方法?