在以下代码中,
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/