Groovy语法

那篇作品看完只是对Groovy有所领会,只是当作学Gradle的放到知识。
设置难题请看计划Groovy开发条件(Windows)

简史

Groovy的1.0本子发表于二〇〇五年七月22日。
2013年的年中,Groovy的2.0版本宣布了。
近年来新型版本是2.4.4。

Java的东西Groovy都能用,包含语法和类库

譬如说,新建三个SuperTest.groovy
输入一下Java代码:

public class SuperTest {

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            System.out.println("Java的东西Groovy都能用");
        }
        System.out.println("随便输入点啥试试");
        Scanner sc = new Scanner(System.in); // 不需要导入java.util包
        String str = sc.next();
        System.out.println("你刚才输入了:" + str);
    }

}

运维结果:

Java的东西Groovy都能用
Java的东西Groovy都能用
Java的东西Groovy都能用
随便输入点啥试试
放开那条PM,让如花来
你刚才输入了:放开那条PM,让如花来

活动导入常用包

在上头的例子里应用了Scanner却不要求导入java.util包,是因为Groovy自动导入下列包:
java.lang
java.util
java.io
java.net
java.math.BigDecimal
java.math.BigInteger
groovy.lang
groovy.util

Groovy特点

从上述Groovy能够实施Java的例证能够感受到到以下四个性情:

  • Groovy继承了Java的享有东西,便是你突然忘了Groovy的语法能够写成Java代码,也正是Groovy和Java混在一块也能执行。
  • Groovy和Java一样运转在JVM,源码都是先编写翻译为class字节码。

除此而外,Groovy又对Java的语法实行了简化,成效拓展了增加。那几个得学了切实语法才能感受到,不过能够先来感触下和Groovy相比较Java有多啰嗦,就拿地方的轮回二遍的事例来说,以下的代码实现了同样的功效:

for (i in 0..2) {
    println 'Java的东西Groovy都能用'
}

或者

3.times {
    println 'Java的东西Groovy都能用'
}

———————–初步语法内容———————–

关键字

<code>
as、assert
break
case、catch、class、const、continue
def、default、do
else、enum、extends
false、finally、for
goto
if、implements、import、in、instanceof、interface
new、null
package
return
super、switch
this、throw、throws、trait、true、try
while
</code>

语句不要求分号结尾

写了也没事

注释

// 单行注释
println "hello groovy," /* 我是块注释 */ + "my name is xuhongchuan."

hello groovy,my name is xuhongchuan.

标示符

和Java一样:
建议只用假名、数字、日币$和下划线组成。
以字母,英镑符号$或许下划线
起来,无法以数字开首。

概念变量

用def定义变量,不写def也行。
概念变量不用钦命数据类型且能够随意更换。

def var1 = 1024
var2 = "def不写也行"

var1 = "Integer 改 String"

定义方法

定义方法也是用def当然也能够不写。

// 使用def
def String getName() {
    return "许宏川"
}

// 不写def
String getName() {
    return "许宏川"
}

Groovy全体的法子都有再次回到类型,要是不写则赶回null,没有void。再次来到类型能够简简单单不写,不写的话自动取于最终一行代码的类型。
不写再次回到类型的措施就无法不抬高def。
除此以外return也能够省略不写,都以取最终一行。

def getName() {
    "许宏川"
    1234 // 这行是最后一行,返回Integer
}

主意参数类型可写可不写

// param1写了数据类型, 调用时必须传进来String参数
// param2没写数据类型,调用时可以传进来任意类型的参数
def getString(String param1, param2) {

}

public是暗中同意的

Groovy的类和章程的私下认可修饰符都以public,且能够不难不写。由于修饰符可以不难、方法再次来到类型可以省略、方法参数类型能够总结。所以Java的类和main方法的构造能够简化为:

class SuperTest {

    static main(args) {

    }

}

居然也能够不写类和main结构,直接写main方法里的代码。编写翻译成class文件时会自动给添加上。

字符串

分二种,单引号,双引号和三引号三种。

  • 单引号是输入什么就是何许。
    例如:

println('my name is $ xuhongchuan')

打字与印刷结果为:

my name is $ xuhongchuan

$也健康打字与印刷出来了。

  • 而双引号能够用$引用变量的值。
    例如

name = "xuhongchuan" 
println("my name is $name")

打印结果为:

my name is xuhongchuan
  • 三引号是出口一段文本,能够间接的加空格和换行。
    例如:

println('''这是一段文本。
换行啦!!!
    前面有四个空。。。
有换行啦!!!!''')

打字与印刷结果为:

这是一段文本。
换行啦!!!
    前面有四个空。。。
有换行啦!!!!

以此好啊,想想写sql语句时可随便换行有多舒服。

数据类型

分基本数据类型、容器和闭包二种。

主导数据类型

Groovy是纯面向对象的语言,没有Java里的byte、int、double、boolean等几个值类型。不过有相应的包裹类如Integer、Double和Boolean。在那之中整数私下认可是Integer,浮点数私下认可是。。。你想就是Double?不,是BigDecimal。
假若想显式钦赐Long类型,在末端加L,Double则加D。

var = 5
println var.class

var = 5.5
println var.class

var = 5L
println var.class

var = 5D
println var.class

var = 'hehe'
println var.class

var = false
println var.class

出口结果为:

class java.lang.Integer
class java.math.BigDecimal
class java.lang.Long
class java.lang.Double
class java.lang.String
class java.lang.Boolean

容器类

分List、Map和Range。

  • List

def demoList = [121, 3.14, 'hello', false, null] // 使用[]定义,元素之间用,隔开
println demoList.size // 获取集合大小
prinltn demoList[2] // 获取index为2的元素
// 在结尾添加元素的两种写法
demoList.add(100) 
demoList << 100
//在指定位置添加元素,原本index大于等于3的元素往后退一位
demoList.add(3, 100)
demoList.remove(0) // 删除指定index的元素
demoList -= [3.14, false] // 删除某集合的元素
demoList.clear() // 清空集合
// 使用集合直接调用.each可以对集合进行遍历
demoList.each {
    println it // it是迭代过程中的每一个元素
}
  • Map
    使用[key : value]概念,成分之间用,隔开分离。
    key必须是String,也足以不加引号自动转为String。

def demoMap = ['name' : '许宏川', 'age' : 18, 'isGay' : false]
println demoMap.size() // 获取map大小
println demoMap.name // 通过key获取值
demoMap << ['hehe' : '777'] // 添加元素
// 遍历map
demoMap.each {
    println it.key
    println it.value
}
  • Range

// 范围从1到10
def demoRange = 1..10
// 范围从1到9
def demoRange2 = 1..<10
println(demoRange2.from) // 获取起始值
println(demoRange2.to) // 获取最大值

闭包

闭包是一段代码块,注意闭包也是数据类型,所以能够把闭包作为艺术的参数可能再次来到类型。
假设大家要筛选钦点数n范围内的奇数,普通写法如下:

def getOdd(n) {
    for (i in 1..n) {
        if (i % 2 != 0)
            println i
    }
}

getOdd(10)

如果要收获偶数,又要再写三个格局:

def getEven(n) {
    for (i in 1..n) {
        if (i % 2 == 0)
            println i
    }
}

getEven(10)

那四个法子其实for循环部分的情节是重合的。
而假诺用闭包就不会这么了,例如上面包车型地铁pick接受五个参数,三个参数n,其余一个是闭包(closure是变量名随便取)。再重新3次闭包是三个代码块,那里传进来你想在遍历进程做怎样。至于怎么把方便进度的i传递给闭包,闭包有一个隐式变量叫it,能够吸收接纳二个参数。
看代码:

def pick(n, closure) {
    for (i in 1..n) {
        closure(i)
    }
}

// 打印奇数
pick(10, {
    if (it % 2 != 0) // it代表传进来的参数,也就是上面closure(i)的i
            println it
})

// 打印偶数
pick(10, {
    if (it % 2 == 0)
        println it
})

简单来说循环结构不需求自身写了,你只必要写你想在遍历进程中做如何,例如假设要打字与印刷全体数的平方可以这么:

// 平方
pick(10, {
    println it **= 2
})

那些时候善于思考的同桌就要问了,小编还要自个儿写这一个表现?
亲,那不正是动态的魔力么,哪个人知道你要在遍历进度做哪些啊?可是假诺有一部分表现是隔三差五用的,你也给闭包取个名字固定下来啊就好像定义变量一样。
比如说假如把刚刚的的打字与印刷奇数、打字与印刷偶数和打字与印刷平方定义成变量能够改成那样:

def pick(n, closure) {
    for (i in 1..n) {
        closure(i)
    }
}

// 打印奇数
def getOdd = {
    if (it % 2 != 0)
        println it
}

// 打印偶数
def getEven = {
    if (it % 2 == 0)
        println it
}

// 打印平方
def getSquare = {
    println it **= 2
}

pick(10, getOdd)
pick(10, getEven)
pick(10, getSquare)

这几个时候,善于思考的同学又要问了,隐式变量it只好表示3个参数吧?闭包怎么接收多个参数?
是这么的,用 ->
把参数列表和行事隔离即可。如果大家定义七个闭包接受多少个参数求他们的和:

def getSum = {
    x, y -> println x + y
}

getSum(3, 4) // 闭包可以直接调用

有关闭包还有个说的,正是假设你的闭包不需求吸收参数,可是依然会自动生成隐式it,只可是它的值为null。也正是说,闭包至少含有叁个参数。