Groovy字符串表达式不仅仅是语法糖吗?

时间:2013-11-01 02:59:25

标签: string groovy expression string-concatenation

我在Groovy教程中看到了这段代码 -

import groovy.sql.Sql
sql = Sql.newInstance( 'jdbc:jtds:sqlserver://serverName/dbName-CLASS;domain=domainName', 'username', 'password', 'net.sourceforge.jtds.jdbc.Driver' )
sql.eachRow( 'select * from tableName' ) { println "$it.id -- ${it.firstName} --" }

这是第一次出现Groovy表达式(${}内的任何内容都被评估为表达式,而不是字符串)。我的问题是,这个Groovy表达式功能实际上是否提供了一些新功能?在我看来,这里没有任何东西可以用一个好的旧字符串连接来完成。 IE -

println it.id + " -- " + it.firstName + " --"

4 个答案:

答案 0 :(得分:1)

是。这就是他们的本意。能够将代码和变量添加到字符串中是Groovy的一个功能,使Groovy变得常规。 Groovy中的字符串就像模板一样。

现在,Groovy字符串包含在(“)引号中。但Java中的标准String Groovy包含在撇号(')中。标准{{ 1)} groovy中的字符串不能包含变量引用或代码。

它使代码更容易阅读。有时在Java中查看所有'+'符号作为字符串连接的一部分是PITA。

您更喜欢编码和阅读:

Java

println "$it.id -- ${it.firstName} --"

现在,使用局部变量,它也变得更容易阅读:

Groovy的

println it.id + " -- " + it.firstName + " --"

爪哇:

def name = "some name"
def age = 30
def waist = 42
println "Did $name really have a size $waist waist at age $age?"

答案 1 :(得分:1)

你可以用它们做的另一件事是将它们用作稍微懒惰的模板,即:

def x = "abc"

// Closure expansion rather than variable
def s = "x: ${->x}"

// Prints 'x: abc'
println s

// Change x
x = 400

// Prints 'x: 400'
println s

使用纯字符串连接,您最终会编写打印函数或重复连接代码

另外,不要忘记多行字符串运算符(例如""")和stripMargin方法,它允许您:

def (name,age,sender) = [ 'Alice', 30, 'Tim' ]
println """Hello $name
          |
          |$age today? Congratulations!
          |
          |$sender""".stripMargin()

打印哪些:

Hello Alice

30 today? Congratulations!

Tim

同样,可以使用字符串连接完成,但最终会加载更多类型并且容易出错(imo)

答案 2 :(得分:0)

更多关于Groovy字符串(各种风格)的信息:http://groovy.codehaus.org/Strings+and+GString

我相信任何形式为“字符串”的字符串(即双引号)都是Groovy中的GString实例(不是String)。 GString提供了这些额外的功能。

答案 3 :(得分:0)

通过这里接受的答案,我们似乎已经得出结论,是的,GString(即带有一个或多个${<expr>}表达式的双引号字符串)只是语法糖。 (我接受了接受答案的第一句话:“是的。这就是他们的意思。”)

但是由于懒惰的评估,这似乎是错误的,正如上面提到的tim_yates。

在上面展开一点,如果字符串中的一个或多个表达式是闭包,则仅在GString上调用toString()时对它们进行求值。所以,在groovyconsole中:

def stime = "The time is: ${-> new Date().getTime()}."
println stime
Thread.sleep(500)
println stime
The time is: 1384180043679.
The time is: 1384180044194.

如果不每次都创建一个新字符串,你会用+做什么? (在我参与的两个Java项目中,答案是创建一个Template.java类来完成这类事情。)这表明我不仅仅是 语法糖。或者也许它是语法糖 - 但对于GString类,通常不是java.lang.String或字符串。

另一个例子:

def vals = ['a':42]
def tmpl = "The answer is ${-> vals.a}."
println tmpl
vals.a = 43
println tmpl
The answer is 42.
The answer is 43.

我不确定我是否喜欢这个GString的功能;我习惯于将字符串变为不可变(来自Java)。 Groovy的字符串不是(相当)。看起来你应该能够假设如果两个Groovy'字符串'引用相同的实例,它们将具有相同的文本值,但这不是真的。

http://groovy.codehaus.org/Strings+and+GString(大约一半)