Gradle构建预备:Groovy学习总结笔记

2021年3月8日16:39:05 发表评论 810 次浏览

本文概述

前言

groovy学习笔记

所以为什么学Groovy呢?完全是因为Gradle了,本人并不喜欢Gradle这种构建脚本,因为它使用了另一种语言:Groovy。虽然Groovy可以使用Java的方式编程,但它还是是新语言,多数情况都是使用它的新特性的。而且它是弱语言和动态语言,感觉诸多不方便,所以我刚开始使用Gradle构建的时候,压根不会写,不知道是啥东西,不管三七二十一,配置全部复制一通。

但是因为不会写Gradle脚本,开发还是很多不便,想下编程的日子还有若干年呢,不如学下也好。而构建工具是写所有项目都是几乎要学的,例如C/C++的Make,Java的另一个Maven,要想项目写的顺利,需要在构建工具上花一些精力。

为了解决编写Gradle脚本的问题,用了几天时间学了一下Groovy,本文是一个简单总结,足够应付Gradle脚本了。再有不认识的可以即学即用,而且它兼容Java,实在不知道就用Java写吧。

构建的第一个问题:构建工具要做什么?

我想大部分程序员入门是不重视构建工具的,可能有些机会使用命令行编程,但随后就开始进入IDE编程了,所以这造成后来使用不同的配置或构建脚本会觉得诸多不便,比如我就是。

但是这个问题我写了很多文章都说过了,这里只是结合Gradle和Groovy重复说一次。首先,任何编程基本都是:编写代码,将代码编译成字节码或直接运行。例如Java就需要先将一个Java文件编译成.class字节码文件,然后才能运行。

这里的问题是,如果你只是写一个简单的HelloWorld,那就还好。如果你在开发一个小型的工具,那么这时候就会编写很多个Java文件,这样我们就要手动输入很多次重复而相似的命令进行编译和运行。

这样重复的工作如何简单化呢?这时候构建工具就来了,构建工具基本上就是一个程序,这个程序帮助我们编译或构建整个项目,很多重复的工作就不需要手动处理了。IDE就是嵌入了构建工具和编辑器,另外还有调试器,其它IDE自带的功能都是次要的。

例如在Maven中,我们可以使用mvn compile来编译当前项目,但是目前的构建工具并不仅仅只有编译这个功能,例如还有打包、部署等功能。

构建脚本的工作是什么?

虽然你可能会用构建脚本辅助项目构建了,但是这还不行,随便配置一番,这似乎对项目开发也没多大作用。这还是要记得项目构建的最初需求或动机,它至少要帮我们实现:项目的编译和打包,输出一个最终的产品供我们发布和使用。

下面是构建工具的主要工作:

  • 配置仓库:指定包的来源,有可能构建工具已经有默认的仓库地址了,有时也需要手动再配置。但是有的构建工具是不带包管理器的,也就是不需要配置仓库。
  • 配置依赖:如果当前构建工具需要依赖第三方库,那么我们可以配置一些用到的依赖,这个一般比较简单,到中心仓库搜索并复制配置即可。
  • 构建生命周期:一般构建工具有一个构建生命周期,因为我们不总是编译并生成最终产品,有时我们只是想编译一下,或只是想运行全部的测试,例如常见的清理构建生成文件、编译项目、测试项目、打包项目、发布项目。
  • 构建配置和策略:根据最终的target进行的配置,例如指定构建平台,特定的系统:针对Linux?32位还是64位?根据构建生命周期进行的配置:清理文件策略,编译策略或逻辑,测试测量,打包策略,发布地址配置等等。

其中生命周期是比较重要的,使用任何一个构建工具,务必要了解其构建生命周期。而构建策略则是重点,例如Android的DEX文件方法数超过65536,那你就要手动解决了。

而构建脚本就是要完成以上相关的任务,或者说,构建脚本的配置工具就是这4个了。

Groovy基本特色

Groovy是兼容Java的,支持强类型,所以你完全可以使用Java进行编程,但常用的是弱类型、动态编程,但不要忘记,如果使用动态编程行不通,大可考虑Java。

Groovy定义变量使用def,类似JS中的var,或一些语言中的auto:

def num = 90;
def str = "Groovy"
println num 
println str

上面你可以看到Groovy调用函数是可以不用括号的,这是常用的方式,如果有多个参数,使用逗号分隔即可。另外,语句后面可以不用分号。函数的返回值可以不用return语句,groovy使用函数的最后一个表达式的值作为返回值。

下面是函数的一般使用形式:

def f() {
    println 'function in groovy'
}

def f1(def str) {
    println str
}

def f2(def a, def b) {
    println a + b
}

f()
f1 'Hello Groovy'
f2 3, 4

Groovy中的字符串类似PHP中的字符串,最基本的可以使用单引号,双引号也是基本字符串,但是可以在字符串中引用外部变量或调用函数,三引号的字符串可以换行。

Groovy中的字符串相当于一个字符数组,所以你可以把它当做一个字符列表进行CRUD操作。

def str1 = 'sample string'
def a = 90
def str2 = "number: $a"
def str3 = '''
Groovy Console
'''

println str1
println str2
println str3

def f() {
'Android build.gradle'
}
println "Groovy for: ${f()}"

Groovy支持闭包,现在很多高级语言都支持闭包,例如JS,它的用法很简单,对于它的原理就不再讨论了,只需要看它怎么用就行了。

Closure c1 = { a, b, c ->
    println a + b + c
}
c1(2, 3, 4)

def c2 = { i, j, k ->
    i + j + k
}
c2 3, 4, 5

闭包是groovy是最重要的一个特色,特别在gradle中常用到闭包,例如Android gradle常见的配置:

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
    }
}

其中buildscript是一个函数,后面{}是一个闭包,意思是buildscript的参数是一个闭包。下面我们来实现类似的功能:

def f(c) {
    c()
}

f {
    println 'groovy'
    println 'java'
    println 'android'
    println 'gradle'
}

以上就是groovy的主要特色,其它不再详细讨论,最好你有一些Java、Python、Ruby或JS的编程经验,和它们是类似的。

Groovy API文档

更多的Groovy的类或接口可以参考Groovy API在线文档:http://www.groovy-lang.org/api.html。因为是使用Groovy编程,所以尽量还是使用Groovy的特色,而不是使用原生的Java,如果不太了解可以查看Groovy API的参考文档。

Groovy语法糖

使用Map作为函数的参数:

def printMap(map) {
    println map
}

printMap([1: "11", 2: "22", 3: "33", 4: "44"])
printMap 3: "POM", 4: "Gradle", 5: "Git"

快速创建变量,和变量的值交换:

def (a, b, c) = [[1, 9, 2], 2, 4];
(a, b, c) = [b, c, a]
println a
println b
println c

函数科里化:

def cl1 = {int a, b, c ->
    a + b + c
}
def cl1Curry1 = cl1.curry(1)

shell调用:

println "ls -l".execute().text

总结

上面就是Groovy的主要内容了,如果你有Java基础,那么Groovy其实非常简单,不同的是Groovy的新特性、新的API和一些语法糖,其中最重要的是闭包。

但是不会深入Groovy的开发,能用就行,因为我们最多是使用Groovy作为简单的脚本配置,项目开发还是使用普通的语言,如Java或C/C++。而Groovy是DSL语言,特定领域语言,意思是它只针对特定领域的,而像Java这样的语言,则可以适应普遍的应用开发。

好了,先到这里了,下一篇再详细讨论Gradle的用法和使用。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: