我有一个Java方法:
ratingBar
我在Groovy中使用它是这样的:
progressBar
如何在Groovy中编写调用,使其看起来像:
void copy(Object src, Object dest);
有什么想法吗?
答案 0 :(得分:2)
您不能像在Haskell(或其他函数语言)中那样使用空格分隔的参数编写调用。相反,你需要写:
copyFixP1(src)(dst)
此外,您将第二个变量称为copyFixP1
,但实际上并未修复p1
,copyFixP1
仍需要参数。修复是明确设置copyGroovy
的第一个参数,对'sourcePath'
这样说:
def copyFixedSrc = copyGroovy.curry('sourcePath')
你确实对它进行了测试,因此copyFixP1
是我认为你想要的cp
。
答案 1 :(得分:2)
如果您想创建类似DSL的命令链,您可以利用不带括号和/或点表示法的传递参数。您在问题中提到的cp
命令的最接近形式是:
cp (src) (dest)
在这种情况下, cp
是一个函数,它返回一个调用Java的copy(Object src, Object dest)
方法的闭包。像这样:
def cp(src) {
return { dest ->
copy(src, dest)
}
}
如果您想摆脱括号并接受其他关键字,您可以得到以下内容:
copy src to dest
相当于:
copy(src).to(dest)
copy
方法可以实现为:
def copy(src) {
[to: { dest ->
copy(src, dest)
}]
}
最后,但并非最不重要 - 您实际上可以将此Java方法称为:
copy src, dest
你摆脱了括号,但你需要添加,
来告诉编译器你将两个参数传递给这个函数。
您可以在下面找到所有3种组合的示例:
void copy(Object src, Object dest) {
println "Copying ${src} to ${dest}..."
}
def copy(src) {
[to: { dest ->
copy(src, dest)
}]
}
def cp(src) {
return { dest ->
copy(src, dest)
}
}
def src = "/tmp/test.txt"
def dest = "/tmp/test2.txt"
// Example 1
copy src to dest
// Example 2
cp (src) (dest)
// Example 3
copy src, dest
运行此脚本会产生以下输出:
Copying /tmp/test.txt to /tmp/test2.txt...
Copying /tmp/test.txt to /tmp/test2.txt...
Copying /tmp/test.txt to /tmp/test2.txt...
您可以阅读有关Groovy DSL功能的更多信息here
答案 2 :(得分:2)
以下是一个DSL答案,可以说更像是解决难题的一个问题:它不涉及currying语法,而是提供cp src dest
的单板。但我希望它能说明一些Groovy功能。
如果我们从复制功能开始:
class Copy {
def copy = { a, b -> println "TRACER copy ${a} to ${b}" }
def copyGroovy = { p1, p2 -> copy(p1,p2) }
def copyFixP1 = { p1 -> copyGroovy.curry(p1) }
}
并使用一些元编程方法定义Copier
:
class Copier {
def copyContext
def runContext
def p1, p2
def methodMissing(String name, args) {
p1 = args[0]
return this
}
Object getProperty( String property ) {
p2 = runContext.getProperty(property)
copyContext.copyFixP1(p1)(p2)
}
}
然后考虑以下内容(假设单个Groovy脚本显示为here):
// ----- main
class Example {
def src = "A"
def dest = "B"
def run = { ->
def cp = new Copier(copyContext: new Copy(), runContext: this)
// at long last:
cp src dest
}
}
new Example().run()