在Groovy中连接字符串的最佳(惯用)方法是什么?
选项1:
calculateAccountNumber(bank, branch, checkDigit, account) {
bank + branch + checkDigit + account
}
Run Code Online (Sandbox Code Playgroud)
选项2:
calculateAccountNumber(bank, branch, checkDigit, account) {
"$bank$branch$checkDigit$account"
}
Run Code Online (Sandbox Code Playgroud)
我在旧的Groovy网站上找到了一个关于这个主题的有趣观点:你可以做的事情,但最好不要做.
与在Java中一样,您可以使用"+"符号连接字符串.但是Java只需要将"+"表达式的两个项中的一个作为String,无论它是在第一个位置还是在最后一个.Java将在"+"表达式的非String对象中使用toString()方法.但是在Groovy中,你应该是安全的,你的"+"表达式的第一项以正确的方式实现了plus()方法,因为Groovy将搜索并使用它.在Groovy GDK中,只有Number和String/StringBuffer/Character类实现了连接字符串的plus()方法.为避免意外,请始终使用GStrings.
根据groovy文档,==只是一个"聪明"的equals(),因为它还负责避免NullPointerException.因此,如果对象不为null,则==和equals()应返回相同的值.但是,我在执行以下脚本时遇到意外结果:
println "${'test'}" == 'test'
println "${'test'}".equals('test')
Run Code Online (Sandbox Code Playgroud)
我得到的输出是
true
false
Run Code Online (Sandbox Code Playgroud)
这方面的一个例子可以在这里找到.
这是一个与GStringImpl相关的已知错误还是我缺少的东西?
我正在接受Groovy.语言很好.但我有一个非技术问题.其中一个类叫做GString.在某些情况下,它可能会产生误导.并且提到它在办公室里不太合适,特别是当一些非技术性的女同事在附近时.
我想这还不足以证明在语言中重命名该类.那么当我想说GString时,我怎么能避免说"GString"?
Groovy中的以下代码将GStrings 添加到列表中:
List<String> args = [ 'cmd', "-Dopt=${value}" ]
Run Code Online (Sandbox Code Playgroud)
当我ProcessBuilder用这个列表创建一个时,我得到一个ClassCastException.什么是将列表元素强制转换为正确类型的常规方法?
我有YAML file我的配置名称applications.yaml,该数据将被绑定我:
applications:
- name: service1
port: 8080
path: /servier1
- name: service2
port: 8081
path: /service2
Run Code Online (Sandbox Code Playgroud)
然后,我有一个模板文件applications.config:
<% applications.each { application -> %>
ApplicationName: <%= application.name %>
<% } $ %>
Run Code Online (Sandbox Code Playgroud)
然后放在一起:
@Grab('org.yaml:snakeyaml:1.17')
import org.yaml.snakeyaml.Yaml
Yaml parser = new Yaml()
Map data = parser.load(("applications.yaml" as File).text)
String template_content = new File('applications.config').text
def binding = [applications: data.applications]
def template = new groovy.text.GStringTemplateEngine().createTemplate(template_content).make(binding)
println template.toString()
Run Code Online (Sandbox Code Playgroud)
现在的问题是:该过程的输出是:
ApplicationName: service1
ApplicationName: service2
Run Code Online (Sandbox Code Playgroud)
但是我想要这个:
ApplicationName: service1
ApplicationName: service2 …Run Code Online (Sandbox Code Playgroud) 我有办法在Groovy中对"$ -Strings"进行嵌套评估,例如
def obj = {["name":"Whatever", "street":"ABC-Street", "zip":"22222"]}
def fieldNames = ["name", "street", "zip"]
fieldNames.each{ fieldname ->
def result = " ${{->"obj.${fieldname}"}}" //can't figure out how this should look like
println("Gimme the value "+result);
}
Run Code Online (Sandbox Code Playgroud)
结果应该是:
Gimme the value Whatever
Gimme the value ABC-Street
Gimme the value 22222
Run Code Online (Sandbox Code Playgroud)
我试图解决这个问题要么没有给出正确的结果(例如只是obj.street),要么根本不会编译.到目前为止,我根本就没有理解整个概念.但是,看到这个:http:// groovy.codehaus.org/Strings+and+GString我相信它应该是可能的.
在groovy 文档中,它提到使用 GString 作为键是不好的:
def key = 'some key'
def map = [:]
def gstringKey = "${key.toUpperCase()}"
map.put(gstringKey,'value')
assert map.get('SOME KEY') == null
Run Code Online (Sandbox Code Playgroud)
但是,只需更改 put() 方法以使用下标表示法:
def key = 'some key'
def map = [:]
def gstringKey = "${key.toUpperCase()}"
map[gstringKey] = 'value' // here
assert map.get('SOME KEY') == null
Run Code Online (Sandbox Code Playgroud)
足以导致断言失败。使用 [] 和 put() 方法之间的语义有何不同?下标符号是否有某种隐式转换为 String 可能?
这在GSP页面中按预期工作:
<td>${Foo.findAllByBar(bar)}</td>
Run Code Online (Sandbox Code Playgroud)
但是当添加一个collect语句时代码会中断..
<td>${Foo.findAllByBar(bar).collect { it.name }}</td>
Run Code Online (Sandbox Code Playgroud)
同
Error 500: Could not parse script [...gsp]: startup failed,
...: 129: expecting '}', found ')'
@ line 129, column 196. 1 error`.
Run Code Online (Sandbox Code Playgroud)
我的印象是任何有效的Groovy代码都可以放在GString中${ ... }并正确评估/扩展.我错过了什么?
使用以下代码段我无法gString从地图中检索:
def contents = "contents"
def gString = "$contents"
def map = [(gString): true]
assert map.size() == 1 // Passes
assert gString.hashCode() == map.keySet().first().hashCode() // Passes, same hash code
assert map[gString] // Fails
Run Code Online (Sandbox Code Playgroud)
这怎么可能呢?
断言消息清楚地表明Groovy存在严重错误:
assert map[gString] // Fails
| ||
| |contents
| null
[contents:true]
Run Code Online (Sandbox Code Playgroud)
这不是同一个问题,为什么groovy没有在字典中看到一些值? 第一个答案是:
您将GString实例添加为地图中的键,然后使用String实例搜索它们.
在这个问题中我明确添加GString并尝试检索GString.
也没有为什么在地图中处理GString键的方式有不同的行为?并且Groovy在GStringImpl上使用equals()和==的不同结果对我有一个答案.我不变异任何东西,我不混合String使用GString.
我正在阅读https://groovy-lang.org/closures.html#this 中的 Groovy 闭包文档。有一个关于 GString 行为的问题。
- GStrings 中的闭包
该文件提到了以下内容:
取以下代码:
def x = 1
def gs = "x = ${x}"
assert gs == 'x = 1'
Run Code Online (Sandbox Code Playgroud)
该代码的行为与您预期的一样,但是如果您添加以下内容会发生什么:
x = 2
assert gs == 'x = 2'
Run Code Online (Sandbox Code Playgroud)
你会看到断言失败了!有两个原因:
GString 只懒惰地评估值的 toString 表示
GString 中的语法 ${x} 不代表闭包,而是 $x 的表达式,在创建 GString 时计算。
在我们的示例中,GString 是使用引用 x 的表达式创建的。创建 GString 时,x 的值为 1,因此创建的 GString 值为 1。触发断言时,评估 GString,并使用 toString 将 1 转换为 String。当我们将 x 更改为 2 时,我们确实更改了 x 的值,但它是一个不同的对象,并且 GString 仍然引用旧的。
如果 GString 引用的值发生变化,它只会更改其 toString …