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
复制代码
若是当前这个函数是 Groovy API 或者 Gradle API 中比较经常使用的,好比 println,就能够不带括号。不然仍是带括号。否则,Groovy 可能会把属性和函数调用混淆。java
// 输出 ok
def num = 5.21
switch (num) {
case [5.21, 4, "list"]:
return "ok"
break
default:
break
}
复制代码
可是,其实 Groovy 中并无基本类型,Groovy 做为动态语言, 在它的世界中,全部事物都是对象,就如 Python、Kotlin 同样:全部的基本类型都是属于对象类型。android
若是这个变量就是用于当前类或文件,而不会用于其它类或应用模块,那么,建议使用 def 类型,由于在这种场景下弱类型就足够了。 可是,若是你这个类或变量要用于其它模块的,建议不要使用 def,仍是应该使用 Java 中的那种强类型定义方式,由于使用强类型的定义方式,它不能动态转换为其它类型,它可以保证外界传递进来的值必定是正确的。编程
task groovyString{
doLast{
def name="abc"
println '单引号的变量计算:${name}'
println "双引号的变量计算:${name}"
println "$name" //只有一个变量时可省略大括号
println "${1+2*3}"
}
}
gradle groovyString
> Task :groovyString
单引号的变量计算:${name}
双引号的变量计算:abc
abc
7
复制代码
Groovy 中还新增了一个 GString 类型(当双引号种包含表达式运算时,打印其类型就是GString),编译器能够帮咱们自动在 String 和 GString 之间相互转换,咱们在编写的时候并不须要太过关注它们的区别。bash
task printList {
def numList=[10,11,12,13,14]
println numList.getClass().name
println numList[0]
println numList[1]
println numList[-1]
println numList[1..3]
numList.each{
println it
}
}
$ gradle printList
> Configure project :
java.util.ArrayList
10
11
14
[11, 12, 13]
10
11
12
13
14
task printMap{
def map1=['width':1080,'height':1920]
println map1.getClass().name
println map1['width']
println map1.height
map1.each{
println "key=${it.key}, value=${it.value}"
}
}
$ gradle printMap
> Configure project :
java.util.LinkedHashMap
1080
1920
key=width, value=1080
key=height, value=1920
复制代码
task printMethodReturn{
def add1=method1 1,2
def add2=method1 6,4
println "add1=$add1,add2=$add2"
}
def method1(int a,int b){
if(a>b)
a
else
b
}
$ gradle printMethodReturn
> Configure project :
add1=2,add2=6
复制代码
task printEach{
def list=[11,12,13,14]
//下面几种打印it写法
list.each({println it})
list.each({
println it
})
//方法的最后一个参数是闭包能够放到方法外面
list.each(){
println it
}
//方法能够省略括号
list.each{
println it
}
}
复制代码
若是不声明 public/private 等访问权限的话,Groovy 中类及其变量默认都是 public 的;闭包
task printJavaBean{
Person p=new Person()
println "name=$p.name"
p.name="bob"
println "name=$p.name"
println "age=$p.age"
}
class Person{
private String name
public int getAge(){
28
}
}
gradle printJavaBean
> Configure project :
name=null
name=bob
age=28
复制代码
对于每个 Groovy 脚原本说,它都会生成一个 static void main 函数,main 函数中会调用一个 run 函数,脚本中的全部代码则包含在 run 函数之中app
当咱们在 Groovy 脚本中定义一个变量时,因为它其实是在 run 函数中建立的,因此脚本中的其它方法或其余脚本是没法访问它的。这个时候,咱们须要使用 @Field 将当前变量标记为成员变量jvm
import groovy.transform.Field;
@Field author = JinYang
复制代码
相似lambda表达式函数
task helloClosure{
customEach{
println it
}
eachMap {k,v ->
println "$k is $v"
}
}
def customEach(closure){
for(int i in 1..10){
closure(i)
}
}
//向闭包传参数
def eachMap(closure){
def map=['name':'zhangsan','age':18]
map.each{
closure(it.key,it.value)
}
}
复制代码
groovy支持闭包方法的委托,其闭包有三个属性thisObject,owner,delegate, 调用闭包方法时,由他们肯定使用哪一个对象来处理gradle
task helloDelegate{
new Delegate().test{
println "thisObject:${thisObject.getClass()}"
println "owner:${owner.getClass()}"
println "delegate:${delegate.getClass()}"
method1()
it.method1()
}
}
def method1(){
println "Context this:${this.getClass()} int root"
println "method1 in root"
}
class Delegate{
def method1(){
println "Delegate this:${this.getClass()} in Delegate"
println "method1 in Delegate"
}
def test(Closure<Delegate> closure){
closure(this)
}
}
$ gradle helloDelegate
thisObject:class build_d0vx8g4wj498jzsd4g4xes7j2
owner:class build_d0vx8g4wj498jzsd4g4xes7j2$_run_closure11
delegate:class build_d0vx8g4wj498jzsd4g4xes7j2$_run_closure11
Context this:class build_d0vx8g4wj498jzsd4g4xes7j2 int root
method1 in root
Delegate this:class Delegate in Delegate
method1 in Delegate
复制代码
DSL中,好比Gradle,咱们通常指定delegate为当前的it,这样咱们在闭包内就能够对该it进行配置,或调用其方法ui
task configClosure{
dog{
dogName="bob"
dogAge=7
dumpDog()
}
}
class Dog{
String dogName
int dogAge
def dumpDog(){
println "name is $dogName,age is $dogAge"
}
}
def dog(Closure<Dog> closure){
Dog d=new Dog()
closure.delegate=d
//委托模式优先
closure.setResolveStrategy(Closure.DELEGATE_FIRST)
closure(d)
}
复制代码
领域特定语言,在专而不在全,如Gradle是基于groovy,专门解决自动化构建的DSL
task readLine{
def file =new File("./info.txt")
file.eachLine{ String oneLine ->
println oneLine
}
def text=file.getText()
println text
def text2=file.readLines()
println text2
file.eachLine{oneLine,lineNo ->
println "${lineNo} --> ${oneLine}"
}
}
$ gradle readLine -b file.gradle
> Configure project :
zhangsan
lisi
wangwu
zhaoliu
zhangsan
lisi
wangwu
zhaoliu
[zhangsan, lisi, wangwu, zhaoliu]
1 --> zhangsan
2 --> lisi
3 --> wangwu
4 --> zhaoliu
复制代码
//操做 ism,最后记得关掉
def ism = targetFile.newInputStream()
// do sth
ism.close
//利用闭包来操做 inputStream,其功能更增强大,推荐使用这种写法
targetFile.withInputStream{ ism ->
// 操做 ism,不用 close。Groovy 会自动替你 close
}
复制代码
task writeFile{
def srcFile=new File('./info.txt')
def targetFile=new File('./copyInfo.txt')
targetFile.withOutputStream{ os->
srcFile.withInputStream{ ins->
//利用 OutputStream 的<<操做符重载,完成从 inputstream 到 OutputStream //的输出
os << ins
}
}
}
复制代码
task writeFile2{
try{
def srcFile=new File('./info.txt')
def targetFile=new File('./copyInfo.txt')
if(!targetFile.exists()){
targetFile.createNewFile()
}
srcFile.withReader{reader ->
def lines = reader.readLines()
targetFile.withWriter{writer ->
lines.each{line ->
writer.append(line + "\r\n")
}
}
}
return true
}catch(Exception e){
e.printStackTrace()
}
return false
}
复制代码
此外,咱们也能够经过 withObjectOutputStream/withObjectInputStream 来保存与读取 Object 对象
//保存对象到文件中
task saveObject(){
Person p=new Person()
p.name="alan"
p.age=18
try{
def desFile=new File("./person.txt")
if(!desFile.exists()){
desFile.createNewFile()
}
desFile.withObjectOutputStream{ out ->
out.writeObject(p)
}
return true
}catch(Exception e){
e.printStackTrace()
}
return false
}
//从文件中读取Object
task readObject(){
println "readObject start"
def obj=null
try{
def file=new File("./person.txt")
if(file==null || !file.exists())
println "file==null"
return null
file.withObjectInputStream{input ->
obj=input.readObject()
if(obj!=null){
println "name=$obj.name"
println "age=$obj.age"
}else{
println "obj==null"
}
}
}catch(Exception e){
e.printStackTrace()
}
println "readObject end"
}
class Person{
private String name
private int age
}
//读写的对象须要支持序列化,不然会报java.io.NotSerializableException
复制代码