1

我在 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 表达式的第一次出现(a 中的任何内容${}都被评估为表达式,而不是字符串)。我的问题是,这个 Groovy 表达式特性是否真的提供了一些新功能?在我看来,这里没有什么可以用一个好的旧字符串 concat 来完成。IE -

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

4 回答 4

1

是的。他们就是这样。能够将代码和变量添加到字符串中是 groovy 的一个Groovy特性Groovy。Groovy 中的字符串可以像模板一样。

现在,Groovy字符串用 (") 引号括起来。但标准Java StringinGroovy用撇号 (') 括起来。groovy 中的标准Java字符串不能包含变量引用或代码。

它使代码更易于阅读。Java有时将所有“+”符号作为字符串连接的一部分查看是 PITA。

您更愿意编码和阅读什么:

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

或者

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

爪哇:

String name = "some name";
int age = 30;
int waistSize = 42;
System.out.println("Did " + name + " really have a " + waist + " waist at age  " age + "?";
于 2013-11-01T03:03:22.987 回答
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)

于 2013-11-01T09:44:45.677 回答
0

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

但这似乎是错误的,因为懒惰的评估,正如上面 tim_yates 所指出的那样。

稍微扩展一下,如果字符串中的一个或多个表达式是闭包,则它们仅toString()在 GString 上调用时才被评估。因此,在 groovyconsole 中:

def stime = "The time is: ${-> new Date().getTime()}."
println stime
Thread.sleep(500)
println stime
时间是:1384180043679。
时间为: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
答案是 42。
答案是 43。

我不确定我是否真的喜欢GString 的这个特性;我有点习惯于字符串是不可变的(来自Java)。Groovy 的字符串不是(相当)。似乎您应该能够假设如果两个 Groovy 'strings' 引用同一个实例,它们将具有相同的文本值,但事实并非如此。

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

于 2013-11-11T14:57:47.183 回答
0

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

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

于 2013-11-01T12:08:23.443 回答