groovy学习笔记
groovy是一门类似于java的语言,在java语言的基础上,它吸收了很多脚本的特性,比如python,ruby。跟java一样,每个groovy文件也是编译成class文件,在JVM上运行。但是相比java,groovy的表达方式会更为简便。最近通过http://groovy.zeroleaf.com/core-syntax.html和http://docs.groovy-lang.org/next/html/documentation/来学习groovy。这2篇其实是差不多的,前一个是简单的中文版,是一些groovy的基础语法。后一个是英文原版。
我是一个IDE重度患者,所以选择使用IntelliJ来学习groovy。
#环境配置
下载groovy库
下载安装 sdkman,执行下面命令,按照提示安装即可
1
2$ curl -s http://get.sdkman.io | bash
使环境变量生效
1
2$ source "$HOME/.sdkman/bin/sdkman-init.sh"
安装 Groovy
1
2$ sdk install groovy
此时可以查看groovy版本
1
2
3192:~ fish$ groovy -v Groovy Version: 2.4.7 JVM: 1.7.0_79 Vendor: Oracle Corporation OS: Mac OS X
OK,groovy安装成功
配置IntelliJ
IntelliJ安装的时候默认就会装上groovy插件,我们只要配置下project sdk和groovy library就好了
1、把groovy库从.sdkman复制出来,放到另一个目录。我是把groovy文件夹从/Users/fish/.sdkman/candidates/拷贝到/Users/fish/Documents/。
(因为.sdkman是隐藏文件,所以选择groovy library的时候没办法点到,所以我才把它拷贝出来,这1步应该可以省略的,希望)
2、点击new project,在左边列表选择groovy,右边project sdk选择jdk 1.8,groovy Library点击Create,然后选择/Users/fish/Documents/groovy/2.4.7
3、点击next 就可以了创建一个空的groovy工程了
4、在src下new->groovy script,创建一个groovy脚本,在里面输入
1
2printf "aaa"
点击右键run就可以看到控制台上输出了aaa。
至此,groovy环境配置完成,以后就可以用IntelliJ来开发groovy工程了。
好了,可以开始groovy学习之旅了
标识符
普通标识符
标识符(identifiers)以字母, 美元符号$ 或者下划线开始. 不能以数字开始,如下所示,注意定义一个变量要写def,不用写明变量类型,因为groovy是动态类型的语言。当然写明变量类型也可以,此时就不用写def了。
1
2
3
4
5
6
7
8
9
10
11def name def item3 def with_underscore def $dollarStart //定义了一个String def sex="male" //定义了一个Integer def age=4 //定义了一个map def map = [:]
引用标识符
引用标识符(quoted identifiers)位于点表达式(dotted expression)的点号之后.
- 如下所示可以用
map.'a'
,来访问map的值,这就是引用标识符 - 这里a的引号也可以不用写,
map.a
,结果是一样的。 - 但是如果像L12不写引号的话,就是语法错误,必须加上引号,因为里面有空格
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//定义一个map def map = [:] map."an identifier with a_3_2 space and double quotes" = "ALLOWED" map.'with-dash-signs-and-single-quotes' = "ALLOWED" map.'a'='b' assert map.'a'=='b' assert map.a=='b' //语法错误 //assert map.an identifier with a_3_2 space and double quotes == "ALLOWED" assert map."an identifier with a_3_2 space and double quotes" == "ALLOWED" assert map.'with-dash-signs-and-single-quotes' == "ALLOWED"
groovy 字符串
字符串形式
首先来看下groovy字符串的表现形式,字符串表示的形式多种多样,如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def map = [:] map.'dollar slashy string'="dollar" //如下类型字符串作为引用标识符都是对的 map.'single quote' map."double quote" map.'''triple single quote''' map."""triple double quote""" map./slashy string/ assert map.$/dollar slashy string/$=="dollar" //稍微特殊的GString,也是对的 def firstname = "Homer" map."Simson-${firstname}" = "Homer Simson" assert map.'Simson-Homer' == "Homer Simson"
Groovy有java.lang.String和groovy.lang.GString两中字符串对象类型
单引号和三单引号字符串都是String,不支持插值.
双引号字和三双引号符串在没有插入表达式(interpolated expression)的情况下双引号字符串为 java.lang.String; 如果有, 则为 groovy.lang.GString
当创建如下的字符串:
1
2
3
4
5
6
7def startingAndEndingWithANewline = ''' line one line two line three ''' assert strippedFirstNewline.startsWith('n')
字符串插值
字符串插值,可以用${}进行插值,如下所示
1
2
3
4
5
6
7
8
9def name = 'Guillaume' // a_3_2 plain string def greeting = "Hello ${name}" //plain def greeting2 = "Hello${'girl'}" assert greeting.toString() == 'Hello Guillaume' println(greeting) println(greeting2)
GString toString
当一个方法(不管是在 Java 还是在 Groovy 中实现)期望一个java.lang.String, 但我们传入一个 groovy.lang.GString 实例时, GString 的 toString() 方法会自动, 透明地被调用.
1
2
3
4
5
6
7
8
9
10
11
12String 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 和 String 的哈希码
尽管插值字符串可以用来代替普通 Java 字符串, 但它们与普通字符串在某一方面还是有区别的: 即它们的哈希码(hashCodes)是不一样的. 普通 Java字符串是不可变的, 然而 GString 的结果字符串 表示是可变的, 取决于它的插入值. 即使结果字符串相同, GString 和 String 还是有不同的哈希码.
1
2
3
4
5
6
7
8//左边是插值字符串,右边是普通字符串,hashcode不一致 assert "one: ${1}".hashCode() != "one: 1".hashCode() def key = "a" def m = ["${key}": "letter ${key}"] assert m["a"] == null
backslash
你会发现结果字符串的第一个字符是一个换行符. 可以用反斜杠(backslash)转义换行符来移除该字符:
1
2
3
4
5
6
7def strippedFirstNewline = ''' line one line two line three ''' assert !strippedFirstNewline.startsWith('n')
unicode
groovy还可以支持unicode字符,如下所示
1
2
3
4//欧元货币符号 def a='The Euro currency symbol: u20AC' printf(a)
结果The Euro currency symbol: €
字符
与 Java 不同, Groovy 没有明确的字符字面量. 但是, 你可以通过 3 种不同的方式明确的将 Groovy 字符串转换为字符:
1
2
3
4
5
6
7
8
9char c1 = 'A' assert c1 instanceof Character def c2 = 'B' as char assert c2 instanceof Character def c3 = (char)'C' assert c3 instanceof Character
List
groovy的List本质是java.util.List,但是跟java有些区别,主要是改了下,让使用更方便。
- 创建的时候却像java的数组一样写 比如 下边的numbers不是一个数组,而是一个List(其实是ArrayList).
- List元素访问可以直接用[]访问List的元素,在java里必须用get()方法,方便了不少,比如L6.
- List元素访问可以从后往前,如L7,这个有点像python
- List增加一个元素可以用<<这个操作符
1
2
3
4
5
6
7
8
9
10//定义了一个List def numbers = [1, 2, 3] assert numbers instanceof List assert numbers.size() == 3 assert numbers[2] == 3 assert numbers[-1] == 3 //add letters << 'e'
groovy的List可以放不同类型的东西,比如下边的List放了个int,一个String,一个boolean值
1
2def heterogeneous = [1, "a", true]
数组Array
数组必须指明数据类型,访问数组元素的方法依然是[],和List一致。
1
2
3
4
5
6
7
8
9
10
11String[] arrStr = ['Ananas', 'Banana', 'Kiwi'] assert arrStr instanceof String[] assert !(arrStr instanceof List) def numArr = [1, 2, 3] as int[] assert numArr instanceof int[] assert numArr.size() == 3 assert arrStr[2]=='Kiwi'
map
map实际数据类型是LinkedHashMap,但是创建访问有点像python的dictionary。
- 创建的时候可以用[]
- 访问的时候可以用[]或者.
- 创建时key可以放常量也可以放变量,很有意思,变量用()包含起来
1
2
3
4
5
6
7
8
9
10
11
12
13def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF'] assert colors['red'] == '#FF0000' assert colors.green == '#00FF00' colors['pink'] = '#FF00FF' colors.yellow = '#FFFF00' assert colors.pink == '#FF00FF' assert colors['yellow'] == '#FFFF00' assert colors instanceof java.util.LinkedHashMap
如下所示,上半段代码person里的,key是字符串“ff”,下半段代码里key是ff变量,即“name”字符串。
1
2
3
4
5
6
7
8
9def ff = 'name' def person = [ff: 'Guillaume'] assert !person.containsKey('name') assert person.containsKey('ff') person = [(ff): 'Guillaume'] assert person.containsKey('name') assert !person.containsKey('ff')
数值
groovy会根据数值的大小自动分配数据类型,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40//正数 def a = 1 assert a instanceof Integer // Integer.MAX_VALUE def b = 2147483647 assert b instanceof Integer // Integer.MAX_VALUE + 1 def c = 2147483648 assert c instanceof Long // Long.MAX_VALUE def d = 9223372036854775807 assert d instanceof Long // Long.MAX_VALUE + 1 def e = 9223372036854775808 assert e instanceof BigInteger //负数 def na = -1 assert na instanceof Integer // Integer.MIN_VALUE def nb = -2147483648 assert nb instanceof Integer // Integer.MIN_VALUE - 1 def nc = -2147483649 assert nc instanceof Long // Long.MIN_VALUE def nd = -9223372036854775808 assert nd instanceof Long // Long.MIN_VALUE - 1 def ne = -9223372036854775809 assert ne instanceof BigInteger
String->boolean
String可以直接拿来当boolean值使用,空字符串相当于false,非空字符串相当于true.这里实际上隐式调用了asBoolean方法,转换成了boolean,这种隐式转换非常有意义,后面会看到。
1
2
3assert (!'foo') == false assert (!'') == true
三元运算符
来玩一个代码简化的游戏
1
2
3
4
5
6if (string!=null && string.length()>0) { result = 'Found' } else { result = 'Not found' }
上边这段代码可以用三元运算符来简化
1
2result = (string!=null && string.length()>0)?'Found':'Not found'
实际上利用string的boolean转化,我们还可以更简单,如下所示,其实上面的代码我在java里写过无数次,如果能直接用 string?'Found':'Not found'
来表示真的方便了很多,希望java也能引入类似的语法
1
2result = string?'Found':'Not found'
三元简化
我们经常写如下代码,可以看到重复写了user.name
displayName = user.name ? user.name : 'Anonymous'
groovy想了个办法来简化,可以如下表示
displayName = user.name ?: 'Anonymous'
特殊操作符
空指针保护?
首先有个groovy类Person,然后看下边的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Person { /** 姓名 */ String name /** * 为特定的人创建一个问候方法. * * @param otherPerson 待问候的人 * @return 问候信息 */ String greet(String otherPerson) { "Hello ${otherPerson}" } }
1
2
3
4
5Person[] arrStr = [new Person(), new Person(), null] def person = arrStr[2] def name = person.name assert name == null
这里person会是null,那么person.name就肯定会触发空指针,groovy定义了一种操作符可以避免空指针,那就是加一个?
代码如下所示,这么写代码就方便多了,不用写那么多空判断,但是带来的隐患就是,最后出了问题,难以排查出原因,不好查哪里是null的源头。
1
2
3
4
5
6
7
8
9
10//b1.groovy /** * 空指针保护 * Created by fish on 17/1/7. */ Person[] arrStr = [new Person(), new Person(), null] def person = arrStr[2] def name = person?.name assert name == null
直接获取成员变量@
groovy获取成员变量,会直接调get方法,比如下边user.name会调用User的getName方法,我们这里name是Bob,但是我们复写了getName,所以getName得到Name: Bob,那如果我们想要的是Bob,怎么办呢?groovy提供了一种方法,加个@
1
2
3
4
5
6
7
8
9//b2.groovy class User { String name User(String name) { this.name = name} String getName() { "Name: $name" } } def user = new User('Bob') assert user.name == 'Name: Bob'
直接获取成员变量的代码如下
1
2assert user.@name == 'Bob'
函数
groovy的函数定义一般都是用def定义,形参不需要写明类型,结束的时候用return返回,return可省略
1
2
3
4
5
6
7
8
9
10
11def f(a) { a * a; } def f(a, b) { a * b; } assert f(10) == 100 assert f(5, 10) == 50
- 如果使用void关键字代替def关键字定义函数,则函数的返回值将为null
- 函数不能访问在外部通过def定义的变量:
函数和map
1
2
3
4
5
6
7def f(a,b){ return b+a.x+a.y; } //a=x:2,y:3 b=1 println f(x:2,1,y:3);//输出6 println f(x:2,y:3,1);//输出6
类
groovy的类可以不用写构造函数,而在new的时候指明就可以了。
1
2
3
4
5
6
7
8class Car { String make String model } Car car = new Car(make: 'Peugeot', model: '508') assert car.make == 'Peugeot'
ref
http://docs.groovy-lang.org/next/html/documentation/
http://groovy.zeroleaf.com/core-syntax.html
http://groovy.zeroleaf.com
最后
以上就是虚心春天最近收集整理的关于1groovy入门学习笔记groovy学习笔记标识符groovy 字符串字符List数组Arraymap数值String->boolean三元运算符特殊操作符ref的全部内容,更多相关1groovy入门学习笔记groovy学习笔记标识符groovy内容请搜索靠谱客的其他文章。
发表评论 取消回复