Kotlin中如何懒加载评估函数值,避免策略重复调用
问题分析
你的代码核心问题在于:find方法中调用it.invoke()执行了一次策略来判断是否符合条件,找到匹配策略后又通过?.invoke()再次执行它,导致同一个策略被重复调用。同时需要保留懒加载特性——仅执行到第一个有效策略为止,后续策略不执行。
解决方案
以下是几种优雅且满足需求的写法,均保证策略仅执行一次、懒加载:
方案1:Sequence懒加载+单次执行
利用Kotlin的Sequence实现懒求值,仅执行到第一个符合条件的策略:
fun electStrategy(): T? { return sequenceOf({ attemptStrategyA(x) }, { attemptStrategyB(x) }) .map { it() } // 等价于invoke(),执行策略并获取结果 .firstOrNull { it == true } // 筛选第一个满足有效条件的结果 }
- 逻辑说明:
Sequence的map是懒执行的,只会处理到firstOrNull找到第一个匹配项为止,后续策略不会被调用;每个策略仅执行一次。
方案2:自定义有效条件(firstNotNullOfOrNull)
如果你的“有效策略”判断逻辑更复杂(比如结果非空、满足特定业务规则),可以用firstNotNullOfOrNull灵活处理:
fun electStrategy(): T? { return sequenceOf({ attemptStrategyA(x) }, { attemptStrategyB(x) }) .firstNotNullOfOrNull { strategy -> val result = strategy() // 替换为你的实际有效判断逻辑 result.takeIf { it == true } } }
- 逻辑说明:执行每个策略后,通过
takeIf判断是否有效,有效则返回结果,否则返回null;firstNotNullOfOrNull会取第一个非null的结果,终止后续遍历。
方案3:封装可复用的扩展函数
如果多处需要类似的策略选择逻辑,可封装成扩展函数提升复用性:
// 扩展函数:从策略序列中选出第一个符合条件的结果 fun <T> Sequence<() -> T>.firstValid(predicate: (T) -> Boolean): T? { return this.firstNotNullOfOrNull { strategy -> val result = strategy() result.takeIf(predicate) } } // 使用示例 fun electStrategy(): T? { return sequenceOf({ attemptStrategyA(x) }, { attemptStrategyB(x) }) .firstValid { it == true } }
- 逻辑说明:将策略选择逻辑与业务逻辑分离,代码更具可读性和复用性。
内容的提问来源于stack exchange,提问作者LoreV
相关产品推荐
相关产品推荐

