除了单引号和三引号字符串以外,在所有的字符串字面量中都可以插入任何Groovy表达式。插值是用其值来替换字符串中占位符的行为。占位符表达式是由${}包围的或者以$为前缀的点表达式。当GString被传递给将字符串作为参数的方法时通过调用表达式的toString()方法占位符中的表达式被替换为字符串。
如果在${}中包含剪头“->”时,则表示占位符中的表达式是一个闭包表达式。嵌入的闭包表达式只允许携带不超过一个的参数。闭包表达式的一个重要特性就是延迟加载,如果是普通的表达式,在GString创建时就会传值,而使用闭包表达式,则在GString转为String时,会调用闭包,将新的值传入字符串。
在以$为前缀的点表达式也可以做为占位符,但是点表达式如果是方法调用、或者在{}中、或者包含算数运算符是无效的。比如:
def name = 'World'
def greeting = "Hello ${name}!"
assert greeting.toString() == 'Hello World!'
在占位符${}中可以是任何Groovy表达式都是有效的,如算术表达式;除了表达式外,还可以是语句,但是语句的值是null,所以如果${}中有多个语句的话,最后一个语句应该返回有意义的值,如在GString占位符中1+2可以表示为${def a = 1; def b = 2; a + b},虽然如此,在占位符中还是应该尽可能的坚持使用简单的表达式。如果${}之间不包含任何内容,那么占位符的值就为字符串null。
如果在${}中包含剪头“->”时,则表示占位符中的表达式是一个闭包表达式。嵌入的闭包表达式只允许携带不超过一个的参数。闭包表达式的一个重要特性就是延迟加载,如果是普通的表达式,在GString创建时就会传值,而使用闭包表达式,则在GString转为String时,会调用闭包,将新的值传入字符串。
在以$为前缀的点表达式也可以做为占位符,但是点表达式如果是方法调用、或者在{}中、或者包含算数运算符是无效的。比如:
println "$number.toString()"
会抛出groovy.lang.MissingPropertyException异常,因为Groovy认为你想访问的是number的toString属性,而toString属性是不存在的。
如果需要在GString中使用$,而不是进行转义,则需要在$前加上“\”进行转义。
当一个方法接受一个java.lang.String,但是传递了一个groovy.lang.GString实例时,GString会自动透明的调用toString()方法。
虽然插值字符串可以代替普通的java字符串,但是它们的hashCode是不同的。普通java字符串是不可变的,而插值字符串随着插入的值的变化而变化,所以即使是相同的字符串,GString和String的hashCode也是不同的,所以最好不要使用GString做为Map的键。