gpt4 book ai didi

groovy - 使用带有无效键的 DSL 的 groovy 映射

转载 作者:行者123 更新时间:2023-12-05 05:23:11 25 4
gpt4 key购买 nike

我目前正在构建一个小型 DSL,它需要在键=值对中指定一组属性,但是键可能包含破折号“-”或句点“。”我似乎无法让它工作。

归根结底,我基本上尝试将 Map 作为委托(delegate)传递给闭包,但语法一直吸引着我。

举个例子,考虑一下:

def map = [:]

map.with {
example1 = 123
//exam-ple2 = 123
//'exam-ple3' = 123
//(exam-ple4) = 123
exam.ple5 = 123
//'exam.ple6' = 123
}

示例 1 很好,键等于值且易于阅读。根据编译器,示例 2 和 4 是二进制表达式,不会编译。示例 3 和 6 是常量表达式,无法编译。示例 5 将编译,但在运行时生成 NPE。

我可以使用变通方法,例如将 Map 作为参数传递给闭包,这给出了示例 3 和 6,但它的冗长让我很烦。

有人知道如何巧妙地使用 DSL 属性映射吗?

顺便说一句:我从 java 调用 DSL 而不是 groovy,所以解析方面的技巧必须是 java :)

更新 1:在最初的评论和答案之后..

因此,脚本由 GroovyShell 评估为 DelegatingScript,其中委托(delegate)是 Java 对象。闭包包含来自 .properties 文件的属性,需要在不同的上下文中定义,例如

env {
server-name=someHost1
database.name=someHost2
clientName=someHost3
}

委托(delegate)(Java)对象会将此 block 读取为

public void env(Closure closure) {
Map map = new HashMap();
closure.setDelegate(map);
closure.setResolveStrategy(Closure.DELEGATE_ONLY);
closure.call();
... do something with map...

现在用户(即不是我)可能会从原始属性文件复制到脚本中并更改名称,因此我希望他们无需编辑太多就可以做到这一点,因为这必然会导致打字错误。

正如我所说,我也涵盖了示例 3 和 6,但是,是的,Tim,我忘记了它的隐含 :)

现在我已经将格式更改为字符串,所以 DSL 会写成这样

env '''
server-name=someHost1
database.name=someHost2
clientName=someHost3
'''

也就是说,使用多行字符串而不是闭包,然后读取字符串并使用标准的 java.util.Properties:

public void env(String envString) {
Properties properties = new Properties;
properties.load(new StringReader(envString))
....etc

虽然这可行,但目前唯一的缺点是闭包和多行字符串的组合。

最佳答案

在映射声明中,Groovy 将标识符(例如 example1example2)解析为映射的字符串键:

[ example1: 1, example2: 2 ]

.with{} 上下文中,它可能使用 setProperty(property, value)机制。


但是您的案例具有表达式 exam.pleexample。这些表达式具有优先级,因此,Groovy 将首先尝试解析它们(可能分别使用 exam.getProperty('ple')exam.minus(ple) ).

您有一些语法替代方案,但您必须向 Groovy 明确什么应该是字符串键以及什么是其他表达式:

def map = [
'exam.ple4' : 4, // direct map declaration
example5 : 5 // unambiguous key declaration: no quotes needed
]

map.with {
example1 = 1
put 'exam.ple2', 2 // ambiguous, needs quotes
it.'exam-ple3' = 3 // as per @TimYates suggestion
}

assert map['exam-ple3'] == 3
assert map.'exam.ple2' == 2
assert map['exam.ple4'] == 4
assert map.example5 == 5 // again, no quotes needed for key

关于groovy - 使用带有无效键的 DSL 的 groovy 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38761249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com