请帮助一个元编程配置,这样我就可以添加名为collectWithIndex和injectWithIndex的集合方法,它们以类似于eachWithIndex的方式工作,但当然包括collect和inject的基本功能。新方法将接受两个(带有map的三个)参数闭包,就像eachWithIndex一样。我希望能够在许多不同的脚本中使用这些方法。
用例:
List one = [1, 2, 3]
List two = [10, 20, 30]
assert [10, 40, 90] == one.collectWithIndex { value, index ->
value * two [index]
}
一旦开发了该方法,那么它将如何提供给脚本?我怀疑将使用特殊扩展信息创建一个jar文件,然后将其添加到类路径中。
非常感谢提前
答案 0 :(得分:0)
我仍然确定,这不是一个正确的SO问题,但我将举例说明如何为多个脚本丰富元类。
Idea基于basecript,在其构造函数中为List的metaClass添加了所需的方法。你必须自己实现收集逻辑,通过它很容易。你可以使用包装
import org.codehaus.groovy.control.CompilerConfiguration
class WithIndexInjector extends Script {
WithIndexInjector() {
println("Adding collectWithIndex to List")
List.metaClass.collectWithIndex {
int i = 0
def result = []
for (o in delegate) // delegate is a ref holding initial list.
result << it(o, i++) // it is closure given to method
result
}
}
@Override Object run() {
return null
}
}
def configuration = new CompilerConfiguration()
configuration.scriptBaseClass = WithIndexInjector.name
new GroovyShell(configuration).evaluate('''
println(['a', 'b'].collectWithIndex { it, id -> "[$id]:$it" })
''')
// will print [[0]:a, [1]:b]
如果您希望以更多功能方式执行此操作,而无需重复收集逻辑,则可以使用包装代理关闭。我希望它会慢一点,但也许这不是一个交易。只需将collectWithIndex
替换为以下实现。
List.metaClass.collectWithIndex {
def wrappingProxyClosure = { Closure collectClosure, int startIndex = 0 ->
int i = startIndex
return {
collectClosure(it, i++) // here we keep hold on outer collectClosure and i, and use call former with one extra argument. "it" is list element, provided by default collect method.
}
}
delegate.collect(wrappingProxyClosure(it))
}
offtopic:在SO社区,你当前的问题只会吸引弊端,而不是答案。