Gradle核心思想(三)Groovy快速入門指南

本文首發於微信公衆號「劉望舒」
原文連接:Groovy快速入門看這篇就夠了html

前言

在前面咱們學習了爲何如今要用Gradle?Gradle入門前奏兩篇文章,對Gradle也有了大概的瞭解,這篇文章咱們接着來學習Groovy的基礎,要想學好Gradle,Groovy是必需要掌握的。Groovy僅憑一篇文章是介紹不完的,這裏會帶你們快速的入門Groovy,講解Groovy和Java不一樣的部分,想要更多瞭解Groovy能夠查看Groovy官方文檔Groovy API文檔前端

1.Groovy概述

Groovy是Apache 旗下的一種基於JVM的面向對象編程語言,既能夠用於面向對象編程,也能夠用做純粹的腳本語言。在語言的設計上它吸納了Python、Ruby 和 Smalltalk 語言的優秀特性,好比動態類型轉換、閉包和元編程支持。 Groovy與 Java能夠很好的互相調用並結合編程 ,好比在寫 Groovy 的時候忘記了語法能夠直接按Java的語法繼續寫,也能夠在 Java 中調用 Groovy 腳本。比起Java,Groovy語法更加的靈活和簡潔,能夠用更少的代碼來實現Java實現的一樣功能。java

2.Groovy編寫和調試

Groovy的代碼能夠在Android Studio和IntelliJ IDEA等IDE中進行編寫和調試,缺點是須要配置環境,這裏推薦在文本中編寫代碼並結合命令行進行調試(文本推薦使用Sublime Text)。關於命令行請查看Android Gradle(二)Gradle入門前奏這篇文章。 具體的操做步驟就是:在一個目錄中新建build.gradle文件,在build.gradle中新建一個task,在task中編寫Groovy代碼,用命令行進入這個build.gradle文件所在的目錄,運行gradle task名稱 等命令行對代碼進行調試,本文中的例子都是這樣編寫和調試的。程序員

3.變量

Groovy中用def關鍵字來定義變量,能夠不指定變量的類型,默認訪問修飾符是public。編程

def a = 1;
def int b = 1;
def c = "hello world";
複製代碼

4.方法

方法使用返回類型或def關鍵字定義,方法能夠接收任意數量的參數,這些參數能夠不申明類型,若是不提供可見性修飾符,則該方法爲public。 用def關鍵字定義方法。api

task method <<{
	add (1,2)
	minus 1,2 //1
}
def add(int a,int b) { 
 println a+b //3
}  
def minus(a,b) {//2 
 println a-b
}   
複製代碼

若是指定了方法返回類型,能夠不須要def關鍵字來定義方法。數組

task method <<{
	def number=minus 1,2
	println number
}
int minus(a,b) { 
  return a-b 
}  
複製代碼

若是不使用return ,方法的返回值爲最後一行代碼的執行結果。安全

int minus(a,b) { 
  a-b //4
}  
複製代碼

從上面兩段代碼中能夠發現Groovy中有不少省略的地方:bash

  1. 語句後面的分號能夠省略。
  2. 方法的括號能夠省略,好比註釋1和註釋3處。
  3. 參數類型能夠省略,好比註釋2處。
  4. return能夠省略掉,好比註釋4處。

5.類

Groovy類很是相似於Java類。微信

task method <<{
	def p = new Person()
    p.increaseAge 5
	println p.age
}
class Person {                       
    String name                      
    Integer age =10
    def increaseAge(Integer years) { 
        this.age += years
    }
}
複製代碼

運行 gradle method打印結果爲: 15

Groovy類與Java類有如下的區別:

  1. 默認類的修飾符爲public。
  2. 沒有可見性修飾符的字段會自動生成對應的setter和getter方法。
  3. 類不須要與它的源文件有相同的名稱,但仍是建議採用相同的名稱。

6.語句

6.1 斷言

Groovy斷言和Java斷言不一樣,它一直處於開啓狀態,是進行單元測試的首選方式。

task method <<{
  assert 1+2 == 6
}
複製代碼

輸出結果爲:

Execution failed for task ':method'.
> assert 1+2 == 6
          |  |
          3  false
複製代碼

當斷言的條件爲false時,程序會拋出異常,再也不執行下面的代碼,從輸出能夠很清晰的看到發生錯誤的地方。

6.2 for循環

Groovy支持Java的for(int i=0;i<N;i++)for(int i :array)形式的循環語句,另外還支持for in loop形式,支持遍歷範圍、列表、Map、數組和字符串等多種類型。

//遍歷範圍
def x = 0
for ( i in 0..3 ) {
    x += i
}
assert x == 6
//遍歷列表
def x = 0
for ( i in [0, 1, 2, 3] ) {
    x += i
}
assert x == 6
//遍歷Map中的值
def map = ['a':1, 'b':2, 'c':3]
x = 0
for ( v in map.values() ) {
    x += v
}
assert x == 6
複製代碼

6.3 switch語句

Groovy中的Switch語句不只兼容Java代碼,還能夠處理更多類型的case表達式。

task method <<{
def x = 16
def result = ""

switch ( x ) {
    case "ok":
        result = "found ok"
    case [1, 2, 4, 'list']:
        result = "list"
        break
    case 10..19:
        result = "range"
        break
    case Integer:
        result = "integer"
        break
    default:
        result = "default"
}
assert result == "range"
}
複製代碼

case表達式能夠是字符串、列表、範圍、Integer等等,由於篇幅緣由,這裏只列出了一小部分。

7. 數據類型

Groovy中的數據類型主要有如下幾種:

  • Java中的基本數據類型
  • Groovy中的容器類
  • 閉包

7.1 字符串

Groovy中的基本數據類型和Java大同小異,這裏主要介紹下字符串類型。在Groovy種有兩種字符串類型,普通字符串String(java.lang.String)和插值字符串GString(groovy.lang.GString)。

單引號字符串 在Groovy中單引號字符串和雙引號字符串均可以定義一個字符串常量,只不過單引號字符串不支持插值。

'Android進階解密'
複製代碼

雙引號字符串 要想插值可使用雙引號字符串,插值指的是替換字符串中的佔位符,佔位符表達式爲${}或者以$爲前綴。

def name = 'Android進階之光'
println "hello ${name}"
println "hello $name"
複製代碼

三引號字符串 三引號字符串能夠保留文本的換行和縮進格式,不支持插值。

task method <<{
def name = '''Android進階之光 Android進階解密 Android進階?'''
println name 
}
複製代碼

打印結果爲:

Android進階之光
       Android進階解密
Android進階?
複製代碼

GString String是不可變的,GString倒是可變的,GString和String即便有相同的字面量,它們的hashCodes的值也可能不一樣,所以應該避免使用使用GString做爲Map的key。

assert "one: ${1}".hashCode() != "one: 1".hashCode()
複製代碼

當雙引號字符串中包含插值表達式時,字符串類型爲GString,所以上面的斷言爲true。

7.2 List

Groovy沒有定義本身的集合類,它在Java集合類的基礎上進行了加強和簡化。Groovy的List對應Java中的List接口,默認的實現類爲Java中的ArrayList。

def number = [1, 2, 3]         
assert number instanceof List  
def linkedList = [1, 2, 3] as LinkedList    
assert linkedList instanceof java.util.LinkedList
複製代碼

可使用as操做符來顯式指定List的實現類爲java.util.LinkedList。 獲取元素一樣要比Java要簡潔些,使用[]來獲取List中具備正索引或負索引的元素。

task method <<{
def number  = [1, 2, 3, 4]   
assert number [1] == 2
assert number [-1] == 4 //1 

number << 5     //2 
assert number [4] == 5
assert number [-1] == 5
}
複製代碼

註釋1處的索引-1是列表末尾的第一個元素。註釋2處使用<<運算符在列表末尾追加一個元素。

7.3 Map

建立Map一樣使用[],須要同時指定鍵和值,默認的實現類爲java.util.LinkedHashMap。

def name = [one: '魏無羨', two: '楊影楓', three: '張無忌']   
assert name['one']  == '魏無羨' 
assert name.two  == '楊影楓'
複製代碼

Map還有一個鍵關聯的問題:

def key = 'name'
def person = [key: '魏無羨'] //1
assert person.containsKey('key') 
person = [(key): '魏無羨'] //2 
assert person.containsKey('name') 
複製代碼

註釋1處魏無羨的鍵值是key這個字符串,而不是key變量的值 name。若是想要以key變量的值爲鍵值,須要像註釋2處同樣使用(key),用來告訴解析器咱們傳遞的是一個變量,而不是定義一個字符串鍵值。

7.4 閉包(Closure)

Groovy中的閉包是一個開放的、匿名的、能夠接受參數和返回值的代碼塊。 定義閉包 閉包的定義遵循如下語法:

{ [closureParameters -> ] statements }
複製代碼

閉包分爲兩個部分,分別是參數列表部分[closureParameters -> ]和語句部分 statements 。 參數列表部分是可選的,若是閉包只有一個參數,參數名是可選的,Groovy會隱式指定it做爲參數名,以下所示。

{ println it }     //使用隱式參數it的閉包 
複製代碼

當須要指定參數列表時,須要->將參數列表和閉包體相分離。

{ it -> println it }   //it是一個顯示參數 
{ String a, String b ->                                
    println "${a} is a ${b}"
}   
複製代碼

閉包是groovy.lang.Cloush類的一個實例,這使得閉包能夠賦值給變量或字段,以下所示。

//將閉包賦值給一個變量
def println ={ it -> println it }     
assert println instanceof Closure
//將閉包賦值給Closure類型變量
Closure do= { println 'do!' }                      
複製代碼

調用閉包 閉包既能夠當作方法來調用,也能夠顯示調用call方法。

def code = { 123 }
assert code() == 123 //閉包當作方法調用
assert code.call() == 123 //顯示調用call方法
def isOddNumber = { int i -> i%2 != 0 }                           
assert isOddNumber(3) == true  //調用帶參數的閉包
複製代碼

8. I/O 操做

Groovy的 I/O 操做要比Java的更爲的簡潔。

8.1 文件讀取

咱們能夠在PC上新建一個name.txt,在裏面輸入一些內容,而後用Groovy來讀取該文件的內容:

def filePath = "D:/Android/name.txt"
def file = new File(filePath) ;
file.eachLine {
    println it
}
複製代碼

能夠看出Groovy的文件讀取是很簡潔的,還能夠更簡潔些:

def filePath = "D:/Android/name.txt"
def file = new File(filePath) ;
println file.text
複製代碼

8.2 文件寫入

文件寫入一樣十分簡潔:

def filePath = "D:/Android/name.txt"
def file = new File(filePath);

file.withPrintWriter {
    it.println("三井壽")
    it.println("仙道彰")
}
複製代碼

9. 其餘

9.1 asType

asType能夠用於數據類型轉換:

String a = '23'
int b = a as int
def c = a.asType(Integer)
assert c instanceof java.lang.Integer
複製代碼

9.2 判斷是否爲真

if (name != null && name.length > 0) {}
複製代碼

能夠替換爲

if (name) {}
複製代碼

9.3 安全取值

在Java中,要安全獲取某個對象的值可能須要大量的if語句來判空:

if (school != null) {
    if (school.getStudent() != null) {
        if (school.getStudent().getName() != null) {
            System.out.println(school.getStudent().getName());
        }
    }
}
複製代碼

Groovy中可使用?.來安全的取值:

println school?.student?.name
複製代碼

9.4 with操做符

對同一個對象的屬性進行賦值時,能夠這麼作:

task method <<{
Person p = new Person()
p.name = "楊影楓"
p.age = 19
p.sex = "男"
println p.name
}
class Person {                       
    String name                      
    Integer age
    String sex
}
複製代碼

使用with來進行簡化:

Person p = new Person()
p.with {
   name = "楊影楓"
   age= 19
   sex= "男"
 }   
println p.name
複製代碼

10.總結

本文大概的介紹了Groovy的一些語法,包括:變量、方法、數據類型等等,比起Groovy 官方文檔來講,介紹的並很少,但不要忘了本系列的目標是學習與Android相關的Gradle,Groovy並非重點,咱們只須要了解本文所介紹的內容就夠了,若是碰到哪裏不會再去查找Groovy 官方文檔和Groovy API文檔。

感謝
www.groovy-lang.org/single-page… blog.csdn.net/u011054333/…
blog.csdn.net/yanical/art…
blog.csdn.net/zhaoyanjun6…
blog.csdn.net/singwhatiwa…
www.cnblogs.com/zqlxtt/p/57…
blog.csdn.net/u014099894/…
www.jianshu.com/p/ba55dc163…


不只分享大前端、Java、Android、跨平臺等技術,還有大廠乾貨和程序員成長類文章。

相關文章
相關標籤/搜索