当前位置: 首页 > news >正文

Groovy 的核心语法

太好了!欢迎来到 Groovy 的世界。对于初学者来说,Groovy 是一门非常友好的语言,尤其是如果你已经有 Java 的基础,会发现它非常容易上手。如果没有 Java 基础也没关系,Groovy 的语法清晰而简洁。

我会从最基础的部分开始,为你梳理 Groovy 的核心语法。

1. Groovy 是什么?

Groovy 是一种基于 JVM(Java 虚拟机)的动态语言。这意味着:

  • 它和 Java 是“亲戚”: Groovy 完全兼容 Java 语法。你甚至可以直接把 .java 文件重命名为 .groovy 来运行(当然,不推荐这么做)。
  • 它比 Java 更“灵活”和“简洁”: Groovy 提供了更简单的语法、强大的特性(如闭包、动态类型),让你用更少的代码完成更多的工作。
  • 它常用于: 构建工具(Gradle)、自动化脚本、测试框架(Spock)以及快速的应用程序原型开发。

2. 搭建环境与运行代码

最快的方式是使用 Groovy Web Console: https://groovyconsole.appspot.com/
你可以在浏览器里直接编写和运行 Groovy 代码,无需安装任何东西。

如果你想在本地运行,需要先安装 JDK,然后安装 Groovy SDK。

一个简单的 Groovy 脚本 HelloWorld.groovy

// 单行注释
println "Hello, World!" // 不需要分号,加上也没错
/*多行注释
*/

3. 基础语法要点

变量定义 (Variables)

Groovy 支持 动态类型(像 Python/JS)和 静态类型(像 Java)。

// 1. 动态类型:使用 def 关键字
def name = "Alice" // 字符串
def age = 30       // 整数
def score = 95.5   // 浮点数
def isStudent = true // 布尔值println name.class // 输出:class java.lang.String// 2. 静态类型:明确指定类型
String job = "Developer"
int year = 2024// 重新赋值
name = "Bob" // OK
// year = "Two thousand" // 错误!静态类型检查,不能将字符串赋给整型变量
字符串 (Strings)

Groovy 的字符串非常强大,尤其是 GString(插值字符串)。

// 1. 单引号字符串:普通字符串,不支持插值
def singleQuote = 'I am $name' 
println singleQuote // 输出:I am $name// 2. 双引号字符串:支持插值(核心优势!)
def doubleQuote = "I am $name, and I am ${age + 1} years old next year."
println doubleQuote // 输出:I am Bob, and I am 31 years old next year.// 3. 三引号字符串:支持多行
def multiLine = '''Line 1Line 2Line 3
'''
println multiLine
集合 (Collections)

Groovy 为 List 和 Map 提供了极其简便的语法和强大的方法。

List (列表)

// 1. 定义List
def list = [1, 2, 3, 4] // 默认是 ArrayList
println list[0] // 输出 1 (索引从0开始)
println list[-1] // 输出 4 (支持负索引,从末尾开始)// 2. 添加元素
list << 5 // 等价于 list.add(5)
list += 6// 3. 常用方法
list.each { println it } // 遍历每个元素,`it`是默认参数名
def doubled = list.collect { it * 2 } // 映射为新列表 [2, 4, 6, 8, 10, 12]
def evens = list.findAll { it % 2 == 0 } // 查找所有偶数 [2, 4, 6]

Map (映射/字典)

// 1. 定义Map
def map = [name: "Alice", age: 30, "job": "Developer"] // 键默认是字符串,可加引号也可不加// 2. 访问元素
println map.name    // Alice (类属性方式)
println map['age']  // 30 (类数组方式)
println map.get('job') // Developer (方法方式)// 3. 添加/修改元素
map.country = 'USA'
map['age'] = 31// 4. 遍历
map.each { key, value -> println "$key: $value" 
}
闭包 (Closures)

闭包是 Groovy 的灵魂,它是一个可被延迟执行的代码块,类似于 Java 8 的 Lambda表达式。

// 1. 定义一个闭包
def greet = { name ->println "Hello, $name!"
}// 2. 调用闭包
greet("Bob") // 输出:Hello, Bob!// 3. 作为方法参数(非常常见)
// 假设有一个方法:def runTwice(Closure code) { code(); code() }
def runTwice(code) {code()code()
}runTwice { -> println "Running!" } // 输出两次 "Running!"// 4. 隐式参数 `it`
// 如果一个闭包只有一个参数,你可以省略它的定义,用 `it` 来访问
def printIt = { println it }
printIt("Hello") // 输出:Hellolist.each { println it } // 这里的 `it` 就是列表中的每一个元素
方法 (Methods)

方法定义使用 def 关键字(除非有明确的返回类型)。

// 1. 定义方法
def add(a, b) {return a + b
}
// return 可省略,方法默认返回最后一行表达式的值
def multiply(a, b) { a * b }// 2. 调用方法
def result = add(2, 3)
println result // 5// 3. 带默认参数的方法
def say(message, to = 'World') {println "$message, $to!"
}
say("Hi") // 输出:Hi, World!
say("Hello", "Alice") // 输出:Hello, Alice!
条件与循环 (Condition & Loop)

和 Java 类似,但更简洁。

// 1. 条件语句 if-else (和Java完全一样)
def x = 10
if (x > 5) {println "x is large"
} else if (x > 0) {println "x is small"
} else {println "x is negative"
}// 2. 循环
// 传统 for 循环
for (int i = 0; i < 5; i++) {println i
}// 范围循环 (更Groovy的风格)
for (i in 0..4) { // 0到4(包含4)println i
}(0..4).each { i -> println i } // 用闭包的方式,更函数式

4. 一个综合小例子

// 定义一个任务列表
def tasks = [[name: 'Learn Groovy', time: 60],[name: 'Write Code', time: 120],[name: 'Have Dinner', time: 30]
]// 1. 打印所有任务
println "All tasks:"
tasks.each { println "- ${it.name} (${it.time} mins)" }// 2. 找出耗时超过1小时的任务
println "\nLong tasks:"
def longTasks = tasks.findAll { it.time > 60 }
longTasks.each { task ->println "- ${task.name}"
}// 3. 计算总耗时
def totalTime = tasks.collect { it.time }.sum()
// 更简洁的写法:def totalTime = tasks.sum { it.time }
println "\nTotal time needed: $totalTime minutes"

学习建议

  1. 多动手: 在 Groovy Web Console 上把上面的例子都敲一遍,并尝试修改它们。
  2. 善用闭包: 理解 each, collect, findAll, find 这些闭包方法是用好 Groovy 的关键。
  3. 查阅文档: 遇到问题,优先查看官方文档:Groovy Documentation

当然!对于初学者来说,理解这些闭包方法是Groovy(或类似语言如Kotlin)中非常强大和有趣的一步。它们让你能用非常简洁、易读的方式处理和操作集合(如列表、映射等)。

我会用尽可能简单的方式,配合例子来讲解。

首先,什么是闭包?

你可以把闭包(Closure) 想象成一个“打包好的代码块”或者一个“匿名方法”,它可以被传递、赋值给变量,或者作为参数传递给其他方法(就像我们下面要讲的这些)。在语法上,它通常被包裹在花括号 {} 中。

例如,定义一个简单的闭包:

def sayHello = { println "Hello!" }
// 执行它
sayHello() // 输出: Hello!

一个带参数的闭包:

def greet = { name -> println "Hello, ${name}!" }
greet("World") // 输出: Hello, World!

在集合操作中,我们经常把闭包作为参数传递。


现在,我们来看你问的这几个方法。假设我们有一个水果列表:

def fruits = ["Apple", "Banana", "Orange", "Kiwi"]

1. each - 遍历执行

  • 目的遍历集合中的每个元素,并对每个元素执行一些操作(比如打印它)。它像是加强版的 for 循环。
  • 返回值返回集合本身。这意味着它不会改变或创建新的集合。
  • 什么时候用:当你只是想对集合的每个元素做点什么事(比如打印、计算、修改外部变量),但不关心最终结果时。

例子

// 只是打印每个水果
fruits.each { fruit ->println fruit
}
// 输出:
// Apple
// Banana
// Orange
// Kiwi// 它也可以写成一行(默认参数是 it)
fruits.each { println it }// 因为它返回原集合,所以可以链式调用(但通常不这么干)
fruits.each { println it }.each { println it.toUpperCase() }

关键点each 是用来做事的,不是用来获取结果的。


2. collect - 变换收集

  • 目的变换集合中的每个元素,并将变换后的结果收集到一个新的集合中。在其他语言里,这个方法通常叫 map
  • 返回值:返回一个新的列表,包含所有变换后的元素。原集合不会被改变
  • 什么时候用:当你需要基于原集合创建一个内容不同但大小通常相同的新集合时。

例子

// 把每个水果名变成大写,并收集到一个新列表里
def upperCaseFruits = fruits.collect { fruit ->fruit.toUpperCase()
}
println upperCaseFruits // 输出: [APPLE, BANANA, ORANGE, KIWI]
println fruits // 原列表不变: [Apple, Banana, Orange, Kiwi]// 也可以计算每个水果名字的长度
def nameLengths = fruits.collect { it.length() }
println nameLengths // 输出: [5, 6, 6, 4]

关键点collect 是用来创造新东西的。


3. findAll - 查找所有

  • 目的过滤集合,找出所有满足某个条件的元素。
  • 返回值:返回一个新的列表,包含所有满足条件的元素。如果没找到,返回空列表。原集合不变
  • 什么时候用:当你需要从集合中筛选出符合特定规则的所有元素时。

例子

// 找出所有名字长度大于5的水果
def longNameFruits = fruits.findAll { fruit ->fruit.length() > 5
}
println longNameFruits // 输出: [Banana, Orange]// 找出所有名字以 "A" 开头的水果
def aFruits = fruits.findAll { it.startsWith("A") }
println aFruits // 输出: [Apple]

关键点findAll 是“我全都要”(符合条件的)。


4. find - 查找单个

  • 目的查找并返回第一个满足条件的元素。
  • 返回值:返回找到的第一个元素。如果什么都没找到,则返回 null
  • 什么时候用:当你确信只有一个元素符合条件,或者你只关心找到的第一个元素时。

例子

// 找到第一个名字以 "B" 开头的水果
def firstBFruit = fruits.find { fruit ->fruit.startsWith("B")
}
println firstBFruit // 输出: Banana// 尝试找一个不存在的
def notFound = fruits.find { it == "Grape" }
println notFound // 输出: null

关键点find 是“我只要第一个”。


总结与对比

方法目的返回值是否改变原集合
each遍历执行操作原集合本身
collect变换每个元素的集合
findAll过滤出所有符合条件的的集合
find查找第一个符合条件的单个元素null

一个综合小例子

def numbers = [1, 2, 3, 4, 5, 6]// 1. 用 each 打印每个数
numbers.each { println it }// 2. 用 collect 创建一个每个数平方的新列表
def squares = numbers.collect { it * it } // [1, 4, 9, 16, 25, 36]// 3. 用 findAll 找出所有的偶数
def evens = numbers.findAll { it % 2 == 0 } // [2, 4, 6]// 4. 用 find 找出第一个大于3的数
def firstBigNumber = numbers.find { it > 3 } // 4

希望这个解释能帮助你理解!最好的学习方式就是打开一个编辑器,自己创建列表和映射,然后亲手试试这些强大的方法。玩得开心!

http://www.dtcms.com/a/362102.html

相关文章:

  • 计算机视觉与深度学习 | 传统图像处理技术的未来发展前景分析
  • 算法练习——169.多数元素
  • 焦耳热技术助力顶刊研究:薄层质子交换膜实现高效水电解制氢
  • 深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第八章知识点问答(18题)
  • 在工业质检中,机器视觉与人工检测的决策依据
  • Java类加载机制
  • 亚马逊云代理商:如何选择适合的AWS EC2实例类型?
  • ARM-SPI屏幕案例
  • 1. 叙述与命题
  • 【开题答辩全过程】以 基于JSP的养生网站设计与实现为例,包含答辩的问题和答案
  • 在JAVA中Mybatis的使用
  • GitHub每日最火火火项目(9.1)
  • TDengine 日期时间函数 DAYOFWEEK 使用手册
  • shell编程基础入门-3
  • 人工势场法(APF)路径规划 MATLAB
  • 战略进阶——解读92页培训_战略+概述与基本框架麦肯锡【附全文阅读】
  • 一个好的智能体框架应该是什么样子
  • Transformer的并行计算与长序列处理瓶颈总结
  • Solid Explorer文件管理器:功能强大的安卓文件管理器及网盘文件管理器
  • 2025年职场人士专业证书选择与分析
  • 从 “对话” 到 “共创”:生成式 AI 如何重塑内容创作全流程,普通人也能掌握的高效工具指南
  • Windows 安装配置解压版MongoDb
  • ‌ C++ 继承与派生类
  • 从DevOps到BizDevOps:哪些DevOps工具能够成为业务创新加速引擎?
  • Java网络编程基础 Socket通信入门指南
  • 『C++成长记』vector模拟实现
  • Veo Videos Generation API 对接说明
  • 【LLM】使用 LoRA 对 Qwen/Qwen3-Embedding-0.6B 进行微调
  • 基于单片机智能家居环境监测报警系统Proteus仿真(含全部资料)
  • MySQL 性能调优与 SQL 优化的核心利器