Groovy 'No signature of method' 运行 针对委托关闭

Groovy 'No signature of method' running Closure against delegate

我有一个作为委托针对另一个 Groovy 对象执行的闭包。我能做到:

foo {
    bar {
        major = 1
    }
}

但当我这样做时:

foo {
    bar {
        major 1
    }
}

我得到一个错误:

> No signature of method: my.Bar.major() is applicable for argument types (java.lang.Integer) values: [1]
Possible solutions: setMajor(java.lang.Integer), getMajor(), wait(), any(), setMajor(java.lang.String), wait(long)

栏看起来像:

class Bar {
    Integer major
    Integer getMajor() { return this.major }
    def setMajor(Integer val) { this.major = val }
}

我认为 Groovy 在处理 属性 引用时使 getters/setters 变得透明,并且引用 bar.majorbar.get/setMajor() 相同。我是不是理解错了,或者当你将 Closure 代表放入混合中时,meta class 查找路由是否有所不同?解析策略为DELEGATE_FIRST.

更多上下文:http://forums.gradle.org/gradle/topics/groovy-no-signature-of-method-running-closure-against-delegate

您还必须添加 void major(Integer val)major = 1 是 groovy-setMajor(1) 的缩写,而 major 1major(1) 的缩写。 (参见 Section Optional parenthesis

Optional parenthesis

Method calls in Groovy can omit the parenthesis if there is at least one parameter and there is no ambiguity.

println "Hello world"
System.out.println "Nice cheese Gromit!"

例如:

class X {
    Integer major
    void major(Integer m) { major = m }
}

def x = new X()
x.major = 1 // x.setMajor(1)
assert x.major==1 // x.getMajor()==1
x.major 2 // x.major(2)
assert x.major==2

如果您非常需要这种行为,可以为这种情况添加 methodMissing。例如:

class X {
    Integer major
    def methodMissing(String name, args) {
        if (this.hasProperty(name) && args.size()==1) {
            this."$name" = args[0]
        } else {
            throw new MissingMethodException(name, this.class, args)
        }
    }
}

def x = new X()
x.major = 1
assert x.major==1
x.major 2
assert x.major==2