Groovy 中静态闭包的访问值

发布于 2024-08-19 04:51:41 字数 176 浏览 4 评论 0原文

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

class Person {  
static someMap = { key1: "value1", key2: "value2" }  
}

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

I'd like to store some properties in a static closure and later access them during a method call:

class Person {  
static someMap = { key1: "value1", key2: "value2" }  
}

So how can I write a method within Person, which retrieves this stored data?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往昔成烟 2024-08-26 04:51:41

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

如果您确实想将其作为闭包进行评估(可能是为了创建您自己的 DSL),那么您需要像 John 指出的那样稍微更改您的语法。这是一种使用 Builder 类来评估传递给构建器的内容中的“某物”闭包的方法。

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

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")

For the simple case, you're better off using a map.

If you really do want to evaluate it as a closure (possibly to create your own DSL), you'll need to change your syntax slightly as John points out. Here's one way to do it using a Builder class to evaluate the "something" closure within whatever is passed to the builder.

It uses groovy metaprogramming to intercept calls with method/property missing and to save them off:

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")
浊酒尽余欢 2024-08-26 04:51:41

如果它们需要通过闭包而不是映射来初始化,那么就必须有人运行闭包才能拾取并记录设置的值。

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

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

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

听起来您真正想要的只是定义一张地图。

static someMap = [key1: "value1", key2: "value2"]

If they need to be initialized by a closure, instead of a map, then somebody's got to run the closure in order to pick up and record the values as they're set.

Your syntax there isn't valid. Remember closures are just anonymous methods. Your syntax looks like you're trying to define a map, but closures would need to call methods, set variables or return maps. e.g.

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

Then of course whoever's running the closure needs to have the right metaprogramming to record the results.

It sounds like what you really want is just to define a map.

static someMap = [key1: "value1", key2: "value2"]
貪欢 2024-08-26 04:51:41

这是我想出的来提取静态闭包属性的方法:

class ClosureProps {

       Map props = [:]  
       ClosureProps(Closure c) {  
           c.delegate = this  
           c.each{"$it"()}  
       }  
       def methodMissing(String name, args) {  
           props[name] = args.collect{it}  
       }  
       def propertyMissing(String name) {  
           name  
       }  
}  

// Example  
class Team {

        static schema = {  
            table team  
            id teamID  
            roster column:playerID, cascade:[update,delete]  
        }  
}  
def c = new ClosureProps(Team.schema)  
println c.props.table  

This is what I came up with to extract static closure properties:

class ClosureProps {

       Map props = [:]  
       ClosureProps(Closure c) {  
           c.delegate = this  
           c.each{"$it"()}  
       }  
       def methodMissing(String name, args) {  
           props[name] = args.collect{it}  
       }  
       def propertyMissing(String name) {  
           name  
       }  
}  

// Example  
class Team {

        static schema = {  
            table team  
            id teamID  
            roster column:playerID, cascade:[update,delete]  
        }  
}  
def c = new ClosureProps(Team.schema)  
println c.props.table  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文