Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

Gradle Groovy 基础语法 MD


目录

目录
Groovy 基础
为何要学 Groovy
为何要使用 Groovy
如何编译运行 Groovy
最基本的语法
支持的数据类型
String
闭包
List和Map
闭包的参数
加强的IO
访问xml文件
其他的一些语法特性
Getter和Setter
构造器
Class类型
使用with()操作符
判断是否为真
简洁的三元表达式
捕获任何异常
简洁的非空判断
使用断言
==和equals
switch方法
字符串分行
Import 别名

Groovy 基础

docs文档
api文档
参考1
参考2

为何要学 Groovy

Gradle是目前Android主流的构建工具,不管你是通过命令行还是通过AndroidStudio来build,最终都是通过Gradle来实现的。所以学习Gradle非常重要。

目前国内对Android领域的探索已经越来越深,不少技术领域如插件化、热修复、构建系统等都对Gradle有迫切的需求,不懂Gradle将无法完成上述事情。所以Gradle必须要学习。

Gradle不单单是一个配置脚本,它的背后是几门语言:

  • Groovy Language
  • Gradle DSL
  • Android DSL

DSL的全称是Domain Specific Language,即领域特定语言,或者直接翻译成“特定领域的语言”,再直接点,其实就是这个语言不通用,只能用于特定的某个领域,俗称“小语言”。因此DSL也是语言。

实际上,Gradle脚本大多都是使用groovy语言编写的。

Groovy是一门jvm语言,功能比较强大,细节也很多,全部学习的话比较耗时,对我们来说收益较小,并且玩转Gradle并不需要学习Groovy的全部细节,所以其实我们只需要学一些Groovy基础语法与API即可。

为何要使用 Groovy

Groovy是一种基于JVM的敏捷开发语言,它结合了众多脚本语言的强大的特性,由于同时又能与Java代码很好的结合。一句话:既有面向对象的特性又有纯粹的脚本语言的特性。

由于Groovy运行在JVM上,因此也可以使用Java语言编写的组建。

简单来说,Groovy提供了更加灵活简单的语法大量的语法糖以及闭包特性可以让你用更少的代码来实现和Java同样的功能

如何编译运行 Groovy

Groovy是一门jvm语言,它最终是要编译成class文件然后在jvm上执行,所以Java语言的特性Groovy都支持,Groovy支持99%的java语法,我们完全可以在Groovy代码中直接粘贴java代码。

可以安装Groovy sdk来编译和运行。但是我并不想搞那么麻烦,毕竟我们的最终目的只是学习Gradle。

推荐大家通过这种方式来编译和运行Groovy。

在当面目录下创建build.gradle文件,在里面创建一个task,然后在task中编写Groovy代码即可,如下所示:

task(testGroovy).doLast {println "开始运行自定义task"test()
}def test() {println "执行Groovy语法的代码"System.out.println("执行Java语法的代码!");
}

然后在命令行终端中执行如下命令即可:

gradle testGroovy

> Configure project :app > Task :app:testGroovy
开始运行自定义task
执行Groovy语法的代码
执行Java语法的代码!BUILD SUCCESSFUL in 3s
1 actionable task: 1 executed

我们知道,在Android项目中,我们只要更改build.gradle文件一点内容,AS就会提示我们同步:

但是在我们测试 Groovy 时中,我们更改build.gradle文件后可以不必去同步,执行命令时会自动执行你修改后的最新逻辑。

最基本的语法

Groovy中的类和方法默认都是public权限的,所以我们可以省略public关键字,除非我们想使用private。
Groovy中的类型是弱化的,所有的类型都可以动态推断,但是Groovy仍然是强类型的语言,类型不匹配仍然会报错。
Groovy中通过 def 关键字来声明变量和方法
Groovy中很多东西都是可以省略的,比如

  • 语句后面的分号是可以省略的
  • def 和 变量的类型 中的其中之一是可以省略的(不能全部省略)
  • def 和 方法的返回值类型 中的其中之一是可以省略的(不能全部省略)
  • 方法调用时的圆括号是可以省略的
  • 方法声明中的参数类型是可以省略的
  • 方法的最后一句表达式可作为返回值返回,而不需要return关键字

    省略return关键字并不是一个好的习惯,就如同 if else while 后面只有一行语句时可以省略大括号一样,以后如果添加了其他语句,很有可能会导致逻辑错误

def int a = 1; //如果 def 和 类型同时存在,IDE 会提示你"def是不需要的(is unnecessary)"
def String b = "hello world" //省略分号,存在分号时也会提示你 unnecessary
def c = 1 //省略类型def hello() {  //省略方法声明中的返回值类型println ("hello world");println "hello groovy" //省略方法调用时的圆括号return 1;
}def hello(String msg) {println "hello" + msg //省略方法调用时的圆括号1;                    //省略return
}int hello(msg) { //省略方法声明中的参数类型println msgreturn 1 // 这个return不能省略println "done" //这一行代码是执行不到的,IDE 会提示你 Unreachable statement,但语法没错
}

支持的数据类型

在Groovy中,数据类型有:

  • Java中的基本数据类型
  • Java中的对象
  • Closure(闭包)
  • 加强的List、Map等集合类型
  • 加强的File、Stream等IO类型

类型可以显示声明,也可以用 def 来声明,用 def 声明的类型Groovy将会进行类型推断。
基本数据类型和对象和Java中的一致,只不过在Gradle中,对象默认的修饰符为public

String

String的特色在于字符串的拼接,比如

def a = 1
def b = "hello"
def c = "a=${a}, b=${b}"
println c //a=1, b=hello

闭包

Groovy中有一种特殊的类型,叫做Closure,翻译过来就是闭包,这是一种类似于C语言中函数指针的东西。
闭包用起来非常方便,在Groovy中,闭包作为一种特殊的数据类型而存在,闭包可以作为方法的参数和返回值,也可以作为一个变量而存在
闭包可以有返回值和参数,当然也可以没有。下面是几个具体的例子:

def test() {def closure = { String parameters -> //闭包的基本格式println parameters}def closure2 = { a, b -> // 省略了闭包的参数类型println "a=${a}, b=${b}"}def closure3 = { a ->a + 1 //省略了return}def closure4 = { // 省略了闭包的参数声明println "参数为 ${it}" //如果闭包不指定参数,那么它会有一个隐含的参数 it}closure("包青天") //包青天closure2 10086, "包青天" //a=10086, b=包青天println closure3(1) //2//println closure3 2 //不允许省略圆括号,会提示:Cannot get property '1' on null objectclosure4() //参数为 nullclosure4 //不允许省略圆括号,但是并不会报错closure4 10086 //参数为 10086
}

闭包的一个难题是如何确定闭包的参数(包括参数的个数、参数的类型、参数的意义),尤其当我们调用Groovy的API时,这个时候没有其他办法,只有查询Groovy的文档才能知道。

List和Map

Groovy加强了Java中的集合类,比如List、Map、Set等。

基本使用如下:

def emptyList = []
def list = [10086, "hello", true]
list[1] = "world"
assert list[1] == "world"
println list[0] //10086
list << 5 //相当于 add()
assert 5 in list // 调用包含方法
println list //[10086, world, true, 5]

def range = 1..5
assert 2 in range
println range //1..5
println range.size() //5

def emptyMap = [:]
def map = ["id": 1, "name": "包青天"]
map << [age: 29] //添加元素
map["id"] = 10086 //访问元素方式一
map.name = "哈哈" //访问元素方式二,这种方式最简单
println map //{id=10086, name=哈哈, age=29}

可以看到,通过Groovy来操作List和Map显然比Java简单的多。

上面有一个看起来很奇怪的操作符<<,其实这并没有什么大不了,<<表示向List中添加新元素的意思,这一点从 List文档 当也能查到。

public List leftShift(Object value)

  • Overloads the left shift operator to provide an easy way to append objects to a List. 重载左移位运算符,以提供将对象append到List的简单方法。
  • Parameters: value - an Object to be added to the List.
  • Returns: same List, after the value was added to it.

实际上,这个运算符是大量使用的,并且当你用 leftShift 方法时 IDE 也会提示你让你使用左移位运算符<<替换:

def list = [1, 2]
list.leftShift 3
assert list == [1, 2, 3]
list << 4
println list //[1, 2, 3, 4]

闭包的参数

这里借助Map再讲述下如何确定闭包的参数。比如我们想遍历一个Map,我们想采用Groovy的方式,通过查看文档,发现它有如下两个方法,看起来和遍历有关:

  • Map each(Closure closure):Allows a Map to be iterated through using a closure.
  • Map eachWithIndex(Closure closure):Allows a Map to be iterated through using a closure.

可以发现,这两个each方法的参数都是一个闭包,那么我们如何知道闭包的参数呢?当然不能靠猜,还是要查文档。

public Map each(Closure closure)

  • Allows a Map to be iterated through using a closure. If the closure takes one parameter then it will be passed the Map.Entry otherwise if the closure takes two parameters then it will be passed the key and the value.
  • In general, the order in which the map contents are processed cannot be guaranteed(通常无法保证处理元素的顺序). In practise(在实践中), specialized forms of Map(特殊形式的Map), e.g. a TreeMap will have its contents processed according to the natural ordering(自然顺序) of the map.
def result = ""
[a:1, b:3].each { key, value -> result += "$key$value" } //两个参数
assert result == "a1b3"

def result = ""
[a:1, b:3].each { entry -> result += entry } //一个参数
assert result == "a=1b=3"[a: 1, b: 3].each { println "[${it.key} : ${it.value}]" } //一个隐含的参数 it,key 和 value 是属性名

试想一下,如果你不知道查文档,你又怎么知道each方法如何使用呢?光靠从网上搜,API文档中那么多接口,搜的过来吗?记得住吗?

加强的IO

在Groovy中,文件访问要比Java简单的多,不管是普通文件还是xml文件。怎么使用呢?查来 File文档。

public Object eachLine(Closure closure)

  • Iterates through this file line by line. Each line is passed to the given 1 or 2 arg closure. The file is read using a reader which is closed before this method returns.
  • Parameters: closure - a closure (arg 1 is line, optional arg 2 is line number starting at line 1)
  • Returns: the last value returned by the closure

可以看到,eachLine方法也是支持1个或2个参数的,这两个参数分别是什么意思,就需要我们学会读文档了,一味地从网上搜例子,多累啊,而且很难彻底掌握:

def file = new File("a.txt")
file.eachLine { line, lineNo ->println "${lineNo} ${line}" //行号,内容
}file.eachLine { line ->println "${line}" //内容
}

除了eachLine,File还提供了很多Java所没有的方法,大家需要浏览下大概有哪些方法,然后需要用的时候再去查就行了,这就是学习Groovy的正道。

访问xml文件

Groovy访问xml有两个类:XmlParserXmlSlurper,二者几乎一样,在性能上有细微的差别,不过这对于本文不重要。
groovy.util.XmlParser的 API文档

文档中的案例:

def xml = '<root><one a1="uno!"/><two>Some text!</two></root>'
//或者 def xml = new XmlParser().parse(new File("filePath.xml"))
def rootNode = new XmlParser().parseText(xml) //根节点
assert rootNode.name() == 'root' //根节点的名称
assert rootNode.one[0].@a1 == 'uno!' //根节点中的子节点 one 的 a1 属性的值
assert rootNode.two.text() == 'Some text!'  //根节点中的子节点 two 的内容
rootNode.children().each { assert it.name() in ['one','two'] }

更多的细节查文档即可。

其他的一些语法特性

Getter和Setter

当你在Groovy中创建一个beans的时候,通常我们称为POGOS(Plain Old Groovy Objects),Groovy会自动帮我们创建getter/setter方法。
当你对getter/setter方法有特殊要求,你尽可提供自己的方法,Groovy默认的getter/setter方法会被替换。

构造器

有一个bean

class Server {String nameCluster cluster
}

初始化一个实例的时候你可能会这样写:

def server = new Server()
server.name = "Obelix"
server.cluster = aCluster

其实你可以用带命名的参数的默认构造器,会大大减少代码量:

def server = new Server(name: "Obelix", cluster: aCluster)

Class类型

在Groovy中Class类型的.class后缀不是必须的,比如:

def func(Class clazz) {println clazz
}
func(File.class) //class java.io.File
func(File) //class java.io.File

使用with()操作符

当更新一个实例的时候,你可以使用with()来省略相同的前缀,比如:

Book book = new Book()
book.with {id = 1 //等价于 book.id = 1name = "包青天"start(10086)stop("包青天")
}

判断是否为真

所有类型都能转成布尔值,比如nullvoid相当于0或者相当于false,其他则相当于true,所以:

if (name) {}
//等价于
if (name != null && name.length > 0) {}

在Groovy中可以在类中添加asBoolean()方法来自定义是否为真

简洁的三元表达式

在Groovy中,三元表达式可以更加简洁,比如:

def result = name ?: ""
//等价于
def result = name != null ? name : ""

捕获任何异常

如果你实在不想关心try块里抛出何种异常,你可以简单的捕获所有异常,并且可以省略异常类型:

try {// ...
} catch (any) { //可以省略异常类型// something bad happens
}

这里的any并不包括Throwable,如果你真想捕获everything,你必须明确的标明你想捕获Throwable

简洁的非空判断

在java中,你要获取某个对象的值必须要检查是否为null,这就造成了大量的if语句;在Groovy中,非空判断可以用?.表达式,比如:

println order?.customer?.address
//等价于
if (order != null) {if (order.getCustomer() != null) {if (order.getCustomer().getAddress() != null) {System.out.println(order.getCustomer().getAddress());}}
}

使用断言

在Groovy中,可以使用assert来设置断言,当断言的条件为false时,程序将会抛出异常

def check(String name) {assert name // 检查方法传入的参数是否为空,name non-null and non-empty according to Groovy Truthassert name?.size() > 3
}

==和equals

Groovy里的is()方法等同于Java里的==
Groovy中的==是更智能的equals(),比较两个类的时候,你应该使用a.is(b)而不是==
Groovy中的==可以自动避免NullPointerException异常

status == "包青天"
//等价于Java中的
status != null && status.equals("包青天")

switch方法

在Groovy中,switch方法变得更加灵活,可以同时支持更多的参数类型:

def x = null
def result = ""
switch (x) {case "foo": result = "found foo" //没有 break 时会继续向下判断case "bar": result += "bar"breakcase [4, 5, 6]: result = "list" //匹配集合中的元素breakcase 12..30: result = "range" //匹配某个范围内的元素breakcase Integer: result = "integer" //匹配Integer类型breakcase { it > 3 }: result = "number > 3" //匹配表达式breakcase Number: result = "number" //匹配Number类型breakdefault: result = "default"
}
println result

字符串分行

Java中,字符串过长需要换行时我们一般会这样写:

throw new PluginException("Failed to execute command list-applications:" +" The group with name " +parameterMap.groupname[0] +" is not compatible group of type " +SERVER_TYPE_NAME)

Groovy中你可以用 \ 字符,而不需要添加一堆的双引号:

throw new PluginException("Failed to execute command list-applications: \
The group with name ${parameterMap.groupname[0]} \
is not compatible group of type ${SERVER_TYPE_NAME}")

或者使用多行字符串""":

throw new PluginException("""Failed to execute command list-applications:The group with name ${parameterMap.groupname[0]}is not compatible group of type ${SERVER_TYPE_NAME)}""")

Groovy中,单引号引起来的字符串是java字符串,不能使用占位符来替换变量,双引号引起的字符串则是java字符串或者Groovy字符串。

Import 别名

在java中使用两个类名相同但包名不同的两个类,像java.util.Listjava.wt.List,你必须使用完整的包名才能区分。Groovy中则可以使用import别名:

import java.util.List as jurist //使用别名
import java.awt.List as aList
import java.awt.WindowConstants as WC
import static pkg.SomeClass.foo //静态引入方法

2019-1-12

转载于:https://www.cnblogs.com/baiqiantao/p/10261560.html

Gradle Groovy 基础语法 MD相关推荐

  1. Gradle系列【2】Groovy基础语法篇

    有道无术,术尚可求,有术无道,止于术. 本篇参考w3cschool. 文章目录 Groovy简介 特点 基本语法 Hello World 导入语句 注释 分号 关键词 标识符 数据类型 变量 运算符 ...

  2. Groovy基础语法(自己需要用到的)

    文章目录 Groovy是什么 Groovy语法 一些前提知识 变量 闭包 文件IO Groovy是什么 Groovy是一种动态语言.这种语言比较有特点,它和Java一样,也运行于Java虚拟机中.恩? ...

  3. 一、Groovy语法(一):基础语法

    Groovy基础语法 来源:https://www.jianshu.com/p/8127742e0569 1.Groovy中的变量 1.1.变量的类型:基本类型(java中的int,float,dou ...

  4. 003--【工具】groovy之基础语法

    1.写作背景 目前在进行开源项目学习中,有一些项目时用gradle进行版本控制的,所以在此记录 2.参考网址 基础语法参考网址:https://www.jianshu.com/p/e8dec95c43 ...

  5. Groovy的基础语法

    Groovy的基础语法 Groovy 的语法融合了 Ruby.Python 和 Smalltalk 的一些最有用的功能,同时保留了基于 Java 语言的核心语法.对于Java 开发人员,Groovy ...

  6. Gradle入门系列(二)——groovy高级语法

    groovy高级语法 一.json操作 使用groovy自带的json工具进行json操作 groovy.json.JsonSlurper:将json原数据转成实体对象 groovy.json.Jso ...

  7. Gradle脚本基础全攻略

    转载http://blog.csdn.net/yanbober/article/details/49314255 [工匠若水 http://blog.csdn.net/yanbober 转载请注明出处 ...

  8. java调用android打包_Android Gradle打包基础

    Android gradle打包基础 gradle目录 [代码]java代码:12345MyApp├── build.gradle ( 可以查看Gradle的版本 )├── settings.grad ...

  9. AS 自定义 Gradle plugin 插件 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

最新文章

  1. 感染这种随处可见的“食脑虫”,你可能必死无疑
  2. JS中同步与异步的理解
  3. 轻量级web富文本框——wangEditor使用手册(2)——扩展一个“缩进”功能 demo
  4. (转)jquery插件Validate的使用
  5. 用SQL语句添加删除修改字段及一些表与字段的基本操作 .
  6. 随笔--四个月培训小结
  7. java netbeans桌面_netbeans创建桌面应用程序教程
  8. thymealf 高级用法_史上最详 Thymeleaf 使用教程
  9. 91.解码方法(力扣leetcode) 博主可答疑该问题
  10. Unity3D 2018安装教程
  11. udev介绍及两个小场景应用
  12. java 获取身份证号组成信息
  13. python爬取微信朋友圈
  14. 何新生的英语史(九)—看好莱坞学英语,就是这么简单 2
  15. 计算机检索自考,计算机信息检索02139自考资料(25页)-原创力文档
  16. 同态加密中无符号数之间比较大小
  17. countifs多条件排序_使用Excel COUNTIFS进行多个条件计数
  18. getTextSize()和putText()
  19. 关于cv.waitKey
  20. 外贸邮件群发需要注意哪些?163 vip邮箱登录注册哪个好?

热门文章

  1. 将一张100元按如下要求C语言,aoa三一宝典(计算机二级考试)
  2. github 仓库管理及代码上传
  3. 分布式mysql 不支持存储过程_分布式数据库VoltDB对存储过程的支持
  4. java有没有友元函数_c++中友元函数理解与使用
  5. cisco 模拟器安装及交换机的基本配置实验心得_看完这份1113页的TCP/IP协议+路由与交换机,成功上岸字节跳动...
  6. 使用遗传算法解决N皇后问题
  7. 什么作用计算机辅助工艺,什么是CAPP技术(计算机辅助工艺过程设计)
  8. Android Espresso
  9. Android AdapterViewFlipper
  10. Java数组– java.util.Arrays