如何在Kotlin中实现类似forEach的自定义高阶函数避免代码冗余
实现方案
核心思路
你需要把runMethod的入参从无参函数类型,修改为可接收Wrapper实例作为参数的函数类型,Kotlin支持两种实现方式,都可以达到你要的效果,第二种更贴近标准库forEach的设计风格。
方案1:普通带参函数类型
直接声明函数参数为接收1个Wrapper参数的lambda类型:
class Action { // 假设objects是你的数据源列表,这里补全声明示例 private val objects: List<Any> = listOf() // 入参定义为接收Wrapper参数的函数类型 fun runMethod(method: (Wrapper) -> Unit) { objects.forEach { obj -> val wrapper = Wrapper(obj) method(wrapper) // 把创建好的wrapper传入lambda } } fun runA() { runMethod { wrapper -> wrapper.runA() } // 还可以简写为 runMethod { it.runA() } } fun runB() { runMethod { wrapper -> wrapper.runB() } } } // 示例Wrapper类定义 class Wrapper(private val obj: Any) { fun runA() { /* 逻辑实现 */ } fun runB() { /* 逻辑实现 */ } }
方案2:带接收者的函数类型(更贴近标准库风格,更简洁)
Kotlin支持带接收者的函数类型,用法和系统的apply、run等标准高阶函数一致,lambda内部可以直接访问接收者的成员,不需要额外声明参数:
class Action { private val objects: List<Any> = listOf() // 入参定义为Wrapper作为接收者的函数类型 fun runMethod(method: Wrapper.() -> Unit) { objects.forEach { obj -> val wrapper = Wrapper(obj) wrapper.method() // 直接以wrapper为接收者调用lambda } } fun runA() { // lambda内部直接访问Wrapper的runA方法,不需要额外加参数前缀 runMethod { runA() } } fun runB() { runMethod { runB() } } }
两种方案的区别
- 方案1的lambda需要显式声明Wrapper参数,适合需要同时访问外部类成员和Wrapper成员的场景,避免this指向混淆
- 方案2的写法更简洁,和Kotlin标准库的高阶函数设计风格统一,没有额外参数冗余,更推荐日常使用
内容的提问来源于stack exchange,提问作者Paschalis
相关产品推荐
相关产品推荐

