常量文本字符(text literals)代表了字符链形式的一种东西,叫字符串。groovy可以直接实例化java.lang.String对象。GString在其他语言里也叫插值字符串。
单引号字符串
'a single-quoted string'
单引号字符串就是纯的Java字符串,不支持插值操作。
字符串的连接操作
所有的groovy字符串都可以使用'+'连接操作
assert 'ab' == 'a' + 'b'
三引号字符串
'''a triple-single-quoted string'''
纯Java字符串,不支持插值。三引号字符串可以跨行出现,
def aMultilineString = '''line one
line two
line three'''
转义字符
Escape sequence | Character |
---|---|
\b | backspace |
\f | formfeed |
\n | newline |
\r | carriage return |
\s | single space |
\t | tabulation |
\\ | backslash |
\' | single quote within a single-quoted string (and optional for triple-single-quoted and double-quoted strings) |
\" | double quote within a double-quoted string (and optional for triple-double-quoted and single-quoted strings) |
unicode处理转义字符
使用'\u'加上字符对应的unicode字符值。例如
'The Euro currency symbol: \u20AC'
双引号字符串
"a double-quoted string"
插值字符串
插值字符串表达式被${}包裹,{}可以省略在某些情况下。一个变量替代的插值例子
def name = 'Guillaume' // a plain string
def greeting = "Hello ${name}"
assert greeting.toString() == 'Hello Guillaume'
数学表达式例子
def sum = "The sum of 2 and 3 equals ${2 + 3}"
assert sum.toString() == 'The sum of 2 and 3 equals 5'
只使用$的例子
def person = [name: 'Guillaume', age: 36]
assert "$person.name is $person.age years old" == 'Guillaume is 36 years old'
点号表达式时允许的,但是值有.号时不允许的。
def number = 3.14
shouldFail(MissingPropertyException) {
println "$number.toString()"
}
如果表达式有歧义,需要保留大括号{}
String thing = 'treasure'
assert 'The x-coordinate of the treasure is represented by treasure.x' ==
"The x-coordinate of the $thing is represented by $thing.x" // <= Not allowed: ambiguous!!
assert 'The x-coordinate of the treasure is represented by treasure.x' ==
"The x-coordinate of the $thing is represented by ${thing}.x" // <= Curly braces required
如果需要转义$
or ${},只需要在前面加上'\'符号
assert '$5' == "\$5"
assert '${name}' == "\${name}"
插值特殊例子,闭包表达式
def sParameterLessClosure = "1 + 2 == ${-> 3}"
assert sParameterLessClosure == '1 + 2 == 3'
def sOneParamClosure = "1 + 2 == ${ w -> w << 3}"
assert sOneParamClosure == '1 + 2 == 3'
|
闭包合并表达式,延迟执行
def number = 1
def eagerGString = "value == ${number}"
def lazyGString = "value == ${ -> number }"
assert eagerGString == "value == 1"
assert lazyGString == "value == 1"
number = 2
assert eagerGString == "value == 1"
assert lazyGString == "value == 2"
- We define a
number
variable containing1
that we then interpolate within two GStrings, as an expression ineagerGString
and as a closure inlazyGString
. - We expect the resulting string to contain the same string value of 1 for
eagerGString
. - Similarly for
lazyGString
- Then we change the value of the variable to a new number
- With a plain interpolated expression, the value was actually bound at the time of creation of the GString.
- But with a closure expression, the closure is called upon each coercion of the GString into String, resulting in an updated string containing the new number value.
和Java相关的插值表达式
当一个方法声明了期望得到一个Java字符串的参数,但是传递的实际参数是一个Gstring,传递的参数对象会自动调用toString()方法。隐式调用。
String takeString(String message) {
assert message instanceof String
return message
}
def message = "The message is ${'hello'}"
assert message instanceof GString
def result = takeString(message)
assert result instanceof String
assert result == 'The message is hello'
GString and String hashCodes
即时有相同字符串的值,但是hashcodes都是不一样的。避免使用Gstring做为key..
def key = "a"
def m = ["${key}": "letter ${key}"]
assert m["a"] == null
保存的时候计算的是GString的哈希值,但是在获取的时候使用的是Java String的哈希值。
三个双引号字符值
行为表现和单引号的一样
def name = 'Groovy'
def template = """
Dear Mr ${name},
You're the winner of the lottery!
Yours sincerly,
Dave
"""
assert template.toString().contains('Groovy')
斜杠字符串
def fooPattern = /.*foo.*/
assert fooPattern == '.*foo.*'
不需要做字符转义处理,只有斜线需要做转义处理
def escapeSlash = /The character \/ is a forward slash/
assert escapeSlash == 'The character / is a forward slash'
可以跨行
def multilineSlashy = /one
two
three/
assert multilineSlashy.contains('\n')
支持插值表达式
def color = 'blue'
def interpolatedSlashy = /a ${color} car/
assert interpolatedSlashy == 'a blue car'
美元斜杆字符串表达式
def name = "Guillaume"
def date = "April, 1st"
def dollarSlashy = $/
Hello $name,
today we're ${date}.
$ dollar sign
$$ escaped dollar sign
\ backslash
/ forward slash
$/ escaped forward slash
$$$/ escaped opening dollar slashy
$/$$ escaped closing dollar slashy
/$
assert [
'Guillaume',
'April, 1st',
'$ dollar sign',
'$ escaped dollar sign',
'\\ backslash',
'/ forward slash',
'/ escaped forward slash',
'$/ escaped opening dollar slashy',
'/$ escaped closing dollar slashy'
].every { dollarSlashy.contains(it) }
字符串总结表
String name | String syntax | Interpolated | Multiline | Escape character |
Single-quoted |
|
| ||
Triple-single-quoted |
|
| ||
Double-quoted |
|
| ||
Triple-double-quoted |
|
| ||
Slashy |
|
| ||
Dollar slashy |
|
|
字符
char c1 = 'A'
assert c1 instanceof Character
def c2 = 'B' as char
assert c2 instanceof Character
def c3 = (char)'C'
assert c3 instanceof Character
|