在Groovy中访问静态闭包的值

Dan*_*iel 3 groovy static closures

我想在静态闭包中存储一些属性,然后在方法调用期间访问它们:

class Person {  
static someMap = { key1: "value1", key2: "value2" }  
}
Run Code Online (Sandbox Code Playgroud)

那么如何在Person中编写一个方法来检索这些存储的数据呢?

Ted*_*eid 7

对于简单的情况,您最好使用地图.

如果你真的想把它评估为一个闭包(可能是为了创建你自己的DSL),你需要稍微改变你的语法,就像John指出的那样.这是使用Builder类来评估传递给构建器的任何内容中的"某事"闭包的一种方法.

它使用groovy元编程拦截缺少方法/属性的调用并将其保存:

class SomethingBuilder {
    Map valueMap = [:]

    SomethingBuilder(object) {
        def callable = object.something
        callable.delegate = this
        callable.resolveStrategy = Closure.DELEGATE_FIRST
        callable()
    }

    def propertyMissing(String name) {
        return valueMap[name]
    }

    def propertyMissing(String name, value) {
        valueMap[name] = value
    }

    def methodMissing(String name, args) {
        if (args.size() == 1) {
            valueMap[name] = args[0]
        } else {
            valueMap[name] = args
        }
    }
}

class Person {
    static something = {
        key1 "value1"              // calls methodMissing("key1", ["value1"])
        key2("value2")             // calls methodMissing("key2", ["value2"])
        key3 = "value3"            // calls propertyMissing("key3", "value3")
        key4 "foo", "bar", "baz"   // calls methodMissing("key4", ["foo","bar","baz"])
    }
}

def builder = new SomethingBuilder(new Person())

assert "value1" == builder."key1"  // calls propertyMissing("key1")
assert "value2" == builder."key2"  // calls propertyMissing("key2")
assert "value3" == builder."key3"  // calls propertyMissing("key3")
assert ["foo", "bar", "baz"] == builder."key4"  // calls propertyMissing("key4")
Run Code Online (Sandbox Code Playgroud)


Joh*_*ham 6

如果需要通过闭包而不是映射来初始化它们,那么有人必须运行闭包以便在设置时拾取并记录值.

你的语法无效.记住闭包只是匿名方法.您的语法看起来像是在尝试定义映射,但是闭包需要调用方法,设置变量或返回映射.例如

static someClosure = { key1 = "value1"; key2 = "value2" } // set variables
static someClosure = { key1 "value1"; key2 = "value2" } // call methods
static someClosure = { [key1: "value1", key2: "value2"] } // return a map
Run Code Online (Sandbox Code Playgroud)

当然,无论谁运行闭包都需要使用正确的元编程来记录结果.

听起来你真正想要的只是定义地图.

static someMap = [key1: "value1", key2: "value2"]
Run Code Online (Sandbox Code Playgroud)