Groovy中Map与Closure互转:如何正确将Map转为Closure?
Map与Closure的双向转换:Map转Closure的标准实现方式
已知可以通过以下方式将Closure转换为Map:
Closure cdata = { a = 1 b = 2 c = 3 } Map toObj = [:] cdata.resolveStrategy = Closure.DELEGATE_FIRST cdata.delegate = toObj cdata() println(toObj)
执行后输出[a:1, b:2, c:3]。
但目前不清楚如何标准地将Map转换为Closure,尝试了以下方法虽能运行,但逻辑方向和转Map的思路不一致:
Map mdata = ["a":1, "b":2, "c":3] Closure toClos = {} mdata.every { toClos[it.key] = it.value }
请问是否存在更符合Groovy设计思路的标准转换方法?
两种标准转换方式
根据Groovy的Closure特性,有两种更贴合语言设计思路的转换方式:
方式1:利用Closure委托机制(与转Map逻辑完全对称)
这种方式和你将Closure转Map的思路完全对应,通过设置Closure的delegate为目标Map,并调整解析策略,使得Closure内部的属性访问直接映射到Map的键值:
Map mdata = ["a":1, "b":2, "c":3] Closure toClos = { -> } toClos.delegate = mdata toClos.resolveStrategy = Closure.DELEGATE_FIRST // 测试:访问Closure属性直接读取Map值 println(toClos.a) // 输出1 // 修改Closure属性会同步更新原Map toClos.b = 20 println(mdata) // 输出[a:1, b:20, c:3]
核心是复用Closure的委托机制:转Map是把Closure的属性赋值给委托Map,转Closure是让Closure的属性访问代理到Map,逻辑完全对称。
方式2:构建关联Map的功能型Closure
如果你需要的是一个能直接输出Map、或在内部直接访问Map属性的Closure,可以用以下两种写法:
Map mdata = ["a":1, "b":2, "c":3] // 写法1:Closure执行后直接返回原Map Closure toClos1 = { mdata } println(toClos1()) // 输出[a:1, b:2, c:3] // 写法2:在Closure内通过with绑定Map上下文,直接访问属性 Closure toClos2 = { -> mdata.with { println(a) // 输出1 println(c) // 输出3 } } toClos2()
原尝试方法的局限性
你原来的方法是给Closure自身动态赋值属性(toClos[it.key] = it.value),本质是把Closure当作一个独立的Map容器使用,但它和原Map没有关联——修改Closure的属性不会同步到原Map,反之亦然,并非真正意义上的"Map转Closure"。
内容的提问来源于stack exchange,提问作者Vetsin
相关产品推荐
相关产品推荐

