如何在上下文函数与普通函数间相互转换?I?=>O转I=>O的惯用方法
上下文函数与普通函数的相互转换及类型适配
上下文函数转普通函数
Scala 中的 I ?=> O 上下文函数,本质依赖隐式的 given I 实例才能执行。要转成普通的 I => O 函数,核心是把隐式的上下文参数显式提取为函数参数:
// 示例上下文函数 val ctxFunc: Int ?=> String = (i: Int) => s"Got context value: $i" // 转换为普通函数:显式传递上下文参数 val plainFunc: Int => String = i => ctxFunc(using i) // 更简洁的语法糖写法 val plainFuncShort: Int => String = ctxFunc(using _)
普通函数转上下文函数
反过来,把 I => O 转成 I ?=> O,只需从当前上下文取出 given I 实例,传给普通函数即可:
// 示例普通函数 val plainFunc: Int => String = i => s"Got plain value: $i" // 转换为上下文函数:从上下文获取given实例 val ctxFunc: Int ?=> String = () => plainFunc(summon[Int]) // 简洁写法 val ctxFuncShort: Int ?=> String = plainFunc(summon)
只要当前作用域存在对应的 given Int,直接调用 ctxFunc() 就能得到结果。
I ?=> O 转 I => O 的惯用实现
上面的写法就是 Scala 里的惯用方式。如果需要频繁做这类转换,可以封装一个通用工具函数:
def ctxToPlain[I, O](ctxFunc: I ?=> O): I => O = input => ctxFunc(using input) // 调用示例 val myCtxFunc: String ?=> Boolean = s => s.nonEmpty val myPlainFunc: String => Boolean = ctxToPlain(myCtxFunc)
这个工具函数可以放在项目的通用工具类中,需要时直接调用即可。
本质上这种转换就是把隐式依赖显式化,完全符合 Scala 的设计逻辑,没有特殊技巧,只是利用语言本身的语法特性做适配。
内容的提问来源于stack exchange,提问作者caeus
相关产品推荐
相关产品推荐

