Kotlin能否实现非接口、可自定义名称的函数或函数参数委托?
实现方案
Kotlin 原生暂不支持直接使用 by 关键字委托函数(仅支持属性、接口实现的委托),但可以通过强类型函数类型、属性委托的组合方式实现完全符合需求的效果,同时保证编译期参数校验。
方案1:最简零反射实现(最推荐)
直接利用 Kotlin 函数类型的强类型特性,将委托方法声明为对应签名的函数类型属性,完全不需要额外包装类:
class Foo { fun doSomething(arg1: String, arg2: String, arg3: Boolean) { println("执行:$arg1 $arg2 $arg3") } } class FooDelegate { // 自定义委托后的方法名为execute,直接绑定目标方法引用 val execute = Foo()::doSomething }
调用效果:
// 编译正常 FooDelegate().execute("1", "2", true) // 编译直接报错:参数数量不匹配 FooDelegate().execute("1", "2", "多余参数", false) // 编译直接报错:参数类型不匹配 FooDelegate().execute(1, "2", true)
方案2:贴近你期望的by语法实现
如果要使用和你示例类似的by委托语法,可以通过自定义属性委托返回强类型函数实现:
import kotlin.reflect.KProperty class FunctionDelegate<out T : Function<*>>(private val func: T) { operator fun getValue(thisRef: Any?, property: KProperty<*>): T = func } // 简化创建的顶层工具函数 fun <T : Function<*>> functionDelegate(func: T) = FunctionDelegate(func)
使用方式和你期望的写法几乎一致:
class FooDelegate { val execute by functionDelegate(Foo()::doSomething) }
调用规则和方案1完全一致,所有参数校验都在编译期完成,没有运行时开销。
可选:绑定实例的灵活实现
如果需要外部传入Foo实例,只需要调整FooDelegate的构造函数即可:
class FooDelegate(private val foo: Foo) { val execute by functionDelegate(foo::doSomething) } // 使用时传入实例 val foo = Foo() val delegate = FooDelegate(foo) delegate.execute("a", "b", false)
所有方案都满足:不使用接口、委托后方法名可自定义、编译期参数校验的要求,同时没有反射调用的性能损耗。
内容的提问来源于stack exchange,提问作者htafoya
相关产品推荐
相关产品推荐

