1groovy学习笔记
来源:互联网 发布:unity3d和php开发网站 编辑:程序博客网 时间:2024/04/29 04:10
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,执行下面命令,按照提示安装即可
$ curl -s http://get.sdkman.io | bash
使环境变量生效
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
安装 Groovy
$ sdk install groovy
此时可以查看groovy版本
192:~ fish$ groovy -vGroovy 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脚本,在里面输入
printf "aaa"
点击右键run就可以看到控制台上输出了aaa。
至此,groovy环境配置完成,以后就可以用IntelliJ来开发groovy工程了。
好了,可以开始groovy学习之旅了
标识符
普通标识符
标识符(identifiers)以字母, 美元符号$ 或者下划线开始. 不能以数字开始,如下所示,注意定义一个变量要写def,不用写明变量类型,因为groovy是动态类型的语言。当然写明变量类型也可以,此时就不用写def了。
def namedef item3def with_underscoredef $dollarStart//定义了一个Stringdef sex="male"//定义了一个Integerdef age=4//定义了一个mapdef map = [:]
引用标识符
引用标识符(quoted identifiers)位于点表达式(dotted expression)的点号之后.
- 如下所示可以用
map.'a'
,来访问map的值,这就是引用标识符 - 这里a的引号也可以不用写,
map.a
,结果是一样的。 - 但是如果像L12不写引号的话,就是语法错误,必须加上引号,因为里面有空格
//定义一个mapdef 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字符串的表现形式,字符串表示的形式多种多样,如下所示
def 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
当创建如下的字符串:
def startingAndEndingWithANewline = '''line oneline twoline three'''assert strippedFirstNewline.startsWith('\n')
字符串插值
字符串插值,可以用${}进行插值,如下所示
def name = 'Guillaume' // a_3_2 plain stringdef greeting = "Hello ${name}"//plaindef greeting2 = "Hello${'girl'}"assert greeting.toString() == 'Hello Guillaume'println(greeting)println(greeting2)
GString toString
当一个方法(不管是在 Java 还是在 Groovy 中实现)期望一个java.lang.String, 但我们传入一个 groovy.lang.GString 实例时, GString 的 toString() 方法会自动, 透明地被调用.
String takeString(String message) { assert message instanceof String return message}def message = "The message is ${'hello'}"assert message instanceof GStringdef result = takeString(message)assert result instanceof Stringassert result == 'The message is hello'
GString 和 String 的哈希码
尽管插值字符串可以用来代替普通 Java 字符串, 但它们与普通字符串在某一方面还是有区别的: 即它们的哈希码(hashCodes)是不一样的. 普通 Java字符串是不可变的, 然而 GString 的结果字符串 表示是可变的, 取决于它的插入值. 即使结果字符串相同, GString 和 String 还是有不同的哈希码.
//左边是插值字符串,右边是普通字符串,hashcode不一致assert "one: ${1}".hashCode() != "one: 1".hashCode()def key = "a"def m = ["${key}": "letter ${key}"]assert m["a"] == null
backslash
你会发现结果字符串的第一个字符是一个换行符. 可以用反斜杠(backslash)转义换行符来移除该字符:
def strippedFirstNewline = '''\line oneline twoline three'''assert !strippedFirstNewline.startsWith('\n')
unicode
groovy还可以支持unicode字符,如下所示
//欧元货币符号def a='The Euro currency symbol: \u20AC'printf(a)
结果The Euro currency symbol: €
字符
与 Java 不同, Groovy 没有明确的字符字面量. 但是, 你可以通过 3 种不同的方式明确的将 Groovy 字符串转换为字符:
char c1 = 'A'assert c1 instanceof Characterdef c2 = 'B' as charassert c2 instanceof Characterdef 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增加一个元素可以用<<这个操作符
//定义了一个Listdef numbers = [1, 2, 3] assert numbers instanceof List assert numbers.size() == 3 assert numbers[2] == 3assert numbers[-1] == 3//addletters << 'e'
groovy的List可以放不同类型的东西,比如下边的List放了个int,一个String,一个boolean值
def heterogeneous = [1, "a", true]
数组Array
数组必须指明数据类型,访问数组元素的方法依然是[],和List一致。
String[] 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() == 3assert arrStr[2]=='Kiwi'
map
map实际数据类型是LinkedHashMap,但是创建访问有点像python的dictionary。
- 创建的时候可以用[]
- 访问的时候可以用[]或者.
- 创建时key可以放常量也可以放变量,很有意思,变量用()包含起来
def 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”字符串。
def 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会根据数值的大小自动分配数据类型,
//正数def a = 1assert a instanceof Integer// Integer.MAX_VALUEdef b = 2147483647assert b instanceof Integer// Integer.MAX_VALUE + 1def c = 2147483648assert c instanceof Long// Long.MAX_VALUEdef d = 9223372036854775807assert d instanceof Long// Long.MAX_VALUE + 1def e = 9223372036854775808assert e instanceof BigInteger//负数def na = -1assert na instanceof Integer// Integer.MIN_VALUEdef nb = -2147483648assert nb instanceof Integer// Integer.MIN_VALUE - 1def nc = -2147483649assert nc instanceof Long// Long.MIN_VALUEdef nd = -9223372036854775808assert nd instanceof Long// Long.MIN_VALUE - 1def ne = -9223372036854775809assert ne instanceof BigInteger
String->boolean
String可以直接拿来当boolean值使用,空字符串相当于false,非空字符串相当于true.这里实际上隐式调用了asBoolean方法,转换成了boolean,这种隐式转换非常有意义,后面会看到。
assert (!'foo') == false assert (!'') == true
三元运算符
来玩一个代码简化的游戏
if (string!=null && string.length()>0) { result = 'Found'} else { result = 'Not found'}
上边这段代码可以用三元运算符来简化
result = (string!=null && string.length()>0)?'Found':'Not found'
实际上利用string的boolean转化,我们还可以更简单,如下所示,其实上面的代码我在java里写过无数次,如果能直接用 string?'Found':'Not found'
来表示真的方便了很多,希望java也能引入类似的语法
result = string?'Found':'Not found'
三元简化
我们经常写如下代码,可以看到重复写了user.name
displayName = user.name ? user.name : 'Anonymous'
groovy想了个办法来简化,可以如下表示
displayName = user.name ?: 'Anonymous'
特殊操作符
空指针保护?
首先有个groovy类Person,然后看下边的代码
class Person { /** 姓名 */ String name /** * 为特定的人创建一个问候方法. * * @param otherPerson 待问候的人 * @return 问候信息 */ String greet(String otherPerson) { "Hello ${otherPerson}" }}
Person[] arrStr = [new Person(), new Person(), null]def person = arrStr[2]def name = person.nameassert name == null
这里person会是null,那么person.name就肯定会触发空指针,groovy定义了一种操作符可以避免空指针,那就是加一个?
代码如下所示,这么写代码就方便多了,不用写那么多空判断,但是带来的隐患就是,最后出了问题,难以排查出原因,不好查哪里是null的源头。
//b1.groovy/** * 空指针保护 * Created by fish on 17/1/7. */Person[] arrStr = [new Person(), new Person(), null]def person = arrStr[2]def name = person?.nameassert name == null
直接获取成员变量@
groovy获取成员变量,会直接调get方法,比如下边user.name会调用User的getName方法,我们这里name是Bob,但是我们复写了getName,所以getName得到Name: Bob,那如果我们想要的是Bob,怎么办呢?groovy提供了一种方法,加个@
//b2.groovyclass User { String name User(String name) { this.name = name} String getName() { "Name: $name" }}def user = new User('Bob')assert user.name == 'Name: Bob'
直接获取成员变量的代码如下
assert user.@name == 'Bob'
函数
groovy的函数定义一般都是用def定义,形参不需要写明类型,结束的时候用return返回,return可省略
def f(a) { a * a;}def f(a, b) { a * b;}assert f(10) == 100assert f(5, 10) == 50
- 如果使用void关键字代替def关键字定义函数,则函数的返回值将为null
- 函数不能访问在外部通过def定义的变量:
函数和map
def f(a,b){ return b+a.x+a.y;}//a=x:2,y:3 b=1println f(x:2,1,y:3);//输出6println f(x:2,y:3,1);//输出6
类
groovy的类可以不用写构造函数,而在new的时候指明就可以了。
class 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
- groovy学习笔记1
- Groovy学习笔记(1)
- 1groovy学习笔记
- Groovy学习笔记1--Groovy的下载和安装
- Groovy学习笔记1--Groovy的下载和安装
- Groovy学习笔记
- Groovy 学习笔记 (一)
- Groovy 学习笔记 (二)
- Groovy 学习笔记 (三)
- Groovy学习笔记-Groovlets
- Groovy 学习笔记
- Groovy学习笔记-基础
- groovy学习笔记
- groovy 学习笔记
- Groovy学习笔记
- groovy学习笔记
- groovy学习笔记
- groovy 学习笔记2 IDE
- 贪食蛇的程序
- iOS音频后台播放
- CentOS7安装KVM虚拟机
- 获取 客户端(浏览器)提交的数据乱码问题
- Java Jersey2使用总结
- 1groovy学习笔记
- 集成百度地图
- Mac photoshop cc 2017 破解补丁
- corosync & pacemaker群集-命令
- C++语言--友元类与嵌套类-8.1----友元类、嵌套类
- Activity生命周期详解
- 深入.NET 第二章 上机练习1
- html5网页播放声音
- 【原生JS】addEventListener 和 on 的区别