1、DSL
DSL(Domain Specific Language)是针对某一领域,具有受限表达性的一种计算机程序设计语言。
所谓针对某一领域,其基本思想是“求专不求全”,不像通用目的语言那样目标范围涵盖一切软件问题,而是专门针对某一特定问题的计算机语言。
DSL分为两类,外部DSL和内部DSL。
外部 DSL ,它是一种独立的编程语言,需要从解析器开始实现自己的编译工具,实现成本较高。比如 XML、SQL、JSON等
内部DSL,它是建立在其它宿主语言之上的特殊 DSL,它与宿主语言共享编译与调试工具等基础设施,学习成本更低,也更容易被集成。内部DSL通常是一段合法的程序,但是具有特定的风格。而且只用到了语言一部分特性。比如Groovy DSL主要就是利用Groovy中的闭包特性,不过闭包跟kotlin的高阶函数非常相似,熟悉kotlin的同学更容易理解闭包
2、groovy基础语法
1. 语句定义与变量声明
在Groovy中,变量声明变得更为简单直接。你可以使用def
关键字来声明一个动态类型的变量,无需预先指定其数据类型:
def myVar = "Hello, World!"
这里,myVar
可以自动根据赋值推断其为字符串类型。此外,Groovy也支持传统的静态类型声明,并且完全兼容Java的数据类型。
2. 省略分号与括号
Groovy允许你在编写代码时省略大多数分号(;
),增强了代码的可读性。函数调用时,如果括号内参数只有一个,括号也可以省略,这一点使的由groovy构建的DSL显得非常简洁 :
println "Groovy is cool" // 不需要分号结尾
print "And " + "even cooler!" // 函数调用无需括号,但操作符两侧的对象需空格隔开
//在build.gradle中dependencies 实际是调用了project的dependencies方法传入一个闭包
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
}
//实际是调用了project的task方法
task A {
doLast {
println "task A doLast"
}
}
3. 类定义与继承
Groovy延续了Java的面向对象特性,支持类的定义和继承。不过,Groovy的类定义更加简洁:
class Person {
String name
int age
def introduce() {
"I am $name and I am $age years old"
}
}
def person = new Person(name: 'Alice', age: 30)
println person.introduce()
在这个例子中,字段默认为属性且拥有getter/setter方法,构造器可以通过映射传参。
4. 方法与闭包
官方定义是“Groovy中的闭包是一个开放,匿名的代码块,可以接受参数,返回值并分配给变量”
简而言之,他说一个匿名的代码块,可以接受参数,有返回值。在DSL中,一个DSL脚本就是一个闭包。以下演示几个闭包示例:
def greet = {
println "Hello, World!"
}
// 调用闭包
greet() // 输出 "Hello, World!"
// 定义一个方法,该方法接受一个闭包作为参数并执行它
def executeClosure(closure) {
closure()
}
// 创建一个闭包
def greet = {
println "Hello, Closure!"
}
// 将闭包作为参数传递给方法并执行
executeClosure(greet)// 输出:Hello, Closure!
//当调用的方法需要参数时,Groovy 不要求使用括号,若有多个参数,那么参数之间依然使用逗号分隔;如果不需要参数,那么方法的调用必须显示的使用括号。
def add(number) { 1 + number }
def res = add 1
println res
//也支持级联调用方式,举例来说,`a b c d` 实际上就等同于 `a(b).c(d)`
//定义
ext.total = 0
def a(number) {
total += number
return this
}
def b(number) {
total *= number
return this
}
a 2 b 3
println total
def numbers = [1, 2, 3, 4, 5]
def evenNumbers = numbers.findAll { it % 2 == 0 } // 使用闭包过滤偶数
println evenNumbers
5. 元编程
Groovy强大的元编程能力允许开发者在运行时修改类的行为或创建新的类结构。
// 定义一个简单的Person类
class Person {
String name
// 原始的Person类没有sayHello方法
// 我们将在运行时通过元编程为其添加此方法
}
// 创建一个Person实例
def person = new Person(name: 'Alice')
// 在Groovy中,每个对象都有一个关联的MetaClass
person.metaClass.sayHello = { ->
println "Hello, my name is ${delegate.name}"
}
// 现在可以调用新添加的方法
person.sayHello() // 输出:Hello, my name is Alice(跟kotlin 扩展函数一模一样有木有)
6. 增强的控制结构
Groovy提供了更丰富的条件和循环结构,比如三目运算符的扩展形式和each/in-place迭代等:
[1, 2, 3].each { number -> println number * 2 } // 迭代数组并打印每个元素的两倍
结语
熟悉kotlin的同学一定发现了groovy的语法很多都和kotlin很相似或者几乎一模一样,熟悉kotlin的话上手groovy非常容易。当然,groovy语言的特性不止以上这些,但是我们后面要学习的gradle插件可以使用java、groovy、kotlin来编写,甚至我们用java的方式来写groovy也是没有问题的,只不过浪费了groovy简洁的特性。现在gradle也支持使用kotlin 构建DSL(build.gradle.kts),不过现在android studio创建项目默认还是使用的build.gradle,所以我们这里简单介绍一下。