Ine*_*ego 5 type-inference kotlin 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)
}
Run Code Online (Sandbox Code Playgroud)
我们传递了对包装类方法的引用ClassWithIndecentlyLongName。由于在调用站点上知道此类应作为方法的接收者,因此再次传递该类的名称似乎很尴尬/多余。我希望有些事情::square能奏效,但事实并非如此。如果缺少此功能,可能是什么原因?
(这个问题源于试图重构一些冗长的Java代码,将一类的许多字段转换为另一类的代码。)
使用just ::square意味着它是包或从中调用文件/类的一部分。但这是不正确的。
如果您有这么长的名称,则可以从函数引用切换到实际的lambda,例如:
wrapper.incFunction(1) { square(it) }
Run Code Online (Sandbox Code Playgroud)
如果您有更多参数,则键入别名可能会更有用,例如
typealias Functions = ClassWithIndecentlyLongName // choose a name that's more appropriate
// and calling it as follows:
wrapper.incFunction(1, Functions::square)
Run Code Online (Sandbox Code Playgroud)
或者使用别名导入该类,例如:
import ClassWithIndecentlyLongName as ShortName
Run Code Online (Sandbox Code Playgroud)
但是,更好的方法可能是只丢弃不雅的长名称,而改用更合适的名称。
最后,如果您确实只想使用::square,但仍然可以这样做,只要您提供所需的包装函数,例如:
fun square(c : ClassWithIndecentlyLongName, i : Int) = c.square(i)
// calling it, now works as you wanted:
wrapper.incFunction(1, ::square)
Run Code Online (Sandbox Code Playgroud)
现在:为什么会这样呢?我只能猜。但是对我来说有意义的是,您需要确切指定可以在何处找到该函数。我认为,如果您永远不能确定哪个函数恰好在指定的函数后面,那么它将使代码复杂化。
| 归档时间: |
|
| 查看次数: |
46 次 |
| 最近记录: |