Groovy 字符串:单引号、双引号、三引号
Groovy 作为 JVM 平台上的敏捷语言,在字符串处理方面提供了丰富的语法糖。相比 Java 仅支持双引号字符串,Groovy 根据不同的引号组合赋予了字符串截然不同的特性。理解这三种引号的差异,能让你在日常开发中写出更简洁、更优雅的代码。
1. 单引号字符串:纯粹的字面量
单引号字符串是 Groovy 中最简单的字符串类型。它的行为与 Java 字符串完全一致——不进行任何插值或转义处理。引号内写什么,输出就是什么。
def name = 'Alice'
def greeting = 'Hello, ${name}'
println greeting
```
执行这段代码,输出结果是 `Hello, ${name}`,而非预期的 `Hello, Alice`。这正是单引号的特性:内部内容被当作纯文本处理,`${name}` 不会被解析。
单引号字符串适合以下场景:
- 路径字符串:`'C:\\Users\\Admin\\Documents'`
- 正则表达式模式:`'^\\d{3}-\\d{4}$'`
- 不需要变量替换的固定文本
值得注意的是,单引号字符串虽然不支持插值,但**支持转义字符**。例如 `\n` 换行、`\t` 制表符等都会正常生效。
---
## 2. 双引号字符串:支持插值的灵活表达
双引号字符串是 Groovy 字符串中最常用的类型。它的核心特性是**支持 GString 插值**——可以在字符串中直接嵌入变量或表达式,运行时会被动态计算结果替换。
```groovy
def name = 'Bob'
def age = 28
// 简单变量嵌入
println "My name is ${name}"
// 表达式计算
println "Next year I will be ${age + 1}"
// 属性访问
def person = [name: 'Carol', city: 'Beijing']
println "She lives in ${person.city}"
```
输出结果为:
```
My name is Bob
Next year I will be 29
She lives in Beijing
```
双引号字符串的插值机制非常灵活。对于简单的变量名,可以省略大括号直接写 `$variable`;对于复杂表达式或属性访问,则需要用 `${}` 包裹。这种设计让代码在可读性和表达能力之间取得了很好的平衡。
---
## 3. 三引号字符串:多行文本的解决方案
Groovy 提供了两组三引号语法,分别对应单引号和双引号的特性:
- `''' ... '''`:多行单引号字符串,无插值
- `""" ... """`:多行双引号字符串,支持插值
### 3.1 多行单引号字符串
三单引号最适合编写需要换行的长文本,比如 SQL 查询语句、日志模板等。
```groovy
def sql = '''
SELECT id, name, created_at
FROM users
WHERE status = 'active'
ORDER BY created_at DESC
'''
println sql
```
输出时会保留所有换行格式,且内部的单引号无需转义。如果使用普通单引号,`WHERE status = 'active'` 这行就需要把内部的单引号转义为 `\'`,可读性大打折扣。
### 3.2 多行双引号字符串
三双引号结合了多行书写和插值能力,是生成动态 HTML、JSON 或配置文件的利器。
```groovy
def template = """
<div class="user-card">
<h2>${name}</h2>
<p>Email: ${email}</p>
<p>Role: ${role ?: 'Guest'}</p>
</div>
"""
def user = [name: 'Dave', email: 'dave@example.com']
println template
在实际项目中,三双引号常用于:
- 构建 HTML/XML 片段
- 生成配置文件
- 编写多行错误消息
- SQL 语句拼接
4. 核心差异速查
下表总结了三种引号字符串的关键区别:
| 特性 | 单引号 '...' |
双引号 "..." |
三单引号 '''...''' |
三双引号 """...""" |
|---|---|---|---|---|
| 插值支持 | ❌ | ✅ | ❌ | ✅ |
| 多行支持 | ❌ | ❌ | ✅ | ✅ |
| 转义字符 | ✅ | ✅ | ✅ | ✅ |
| 内部单引号 | 需转义 | 需转义 | 无需转义 | 无需转义 |
| 内部双引号 | 无需转义 | 需转义 | 无需转义 | 无需转义 |
5. 实战场景与最佳实践
场景一:拼接路径
def baseDir = '/opt/app'
def configDir = 'config'
def configFile = 'settings.yml'
// 使用单引号避免意外的插值
def fullPath = "${baseDir}/${configDir}/${configFile}"
```
**场景二:动态 SQL**
```groovy
def table = 'users'
def status = 'active'
def limit = 10
// 三双引号支持插值,三单引号内的单引号无需转义
def query = """
SELECT * FROM ${table}
WHERE status = '${status}'
LIMIT ${limit}
"""
场景三:字符串比较
def a = 'hello'
def b = 'hello'
println a == b // true
println a.is(b) // true,is() 比较内存地址
def c = new String('hello')
println a == c // true,equals 语义
println a.is(c) // false,不同对象
Groovy 的字符串设计体现了"约定优于配置"的理念。默认情况下,单引号提供确定性行为,双引号提供灵活性,而三引号解决了多行文本的痛点。根据实际需求选择合适的引号类型,能显著提升代码的可读性和维护性。

暂无评论,快来抢沙发吧!