Groovy 入门之语法和变量定义

9,372 阅读9分钟

Groovy是什么

Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy 可以使用其他 Java 语言编写的库(百度百科)。

把Groovy看做是敏捷开发语言,主要因为它不像Java语言有那么多严格的规范。如果使用过类似JavaScript这种脚本语言,会更容易明白它的语法。Groovy也是面向对象的编程语言,但是它也可以用作纯粹的脚本语言。使用该语言我们不必编写过多的代码,同时又具有闭包和动态语言的特性。

下面四种方式都会输出“hello world”,而且是不需要放在main方法中就可以执行,当然了放在main中也可以执行。

System.out.println("hello world");

System.out.println"hello world";

println("hello world")

println"hello world"

看到上面这几行代码,可能就有人对它嗤之以鼻了,特别是对代码有洁癖的人,上面代码算什么,有时候加括号而且行末分号可有可无。你可以痛斥它语法上的不规范,但是不可否定它语法上的简洁性,语法上的不规范侧面上体现出这门语言的灵活性。

Groovy是基于JVM的语言,所以它可以与Java无缝对接。Groovy可以集成所有已经存在的Java对象和类库,且可以直接编译成Java字节码,这样可以在任何使用Java的地方使用Groovy。类似地,用标准 Java 代码编写的内容也可以在 Groovy 中重用。

Groovy编写的文件扩展名是.groovy,学习Groovy官网是groovy-lang.org,当然了做Android开发的人员可以直接用Gradle构建工具来运行Groovy,这时候扩展名是.gradle。

为什么要学习Groovy

为什么要学习Groovy,简单来说就是Groovy可以用较少的代码实现较多的功能。

  • Groovy 的松散的Java 语法允许省略分号和修改符。
  • 除非另行指定,Groovy 的所有内容都为 public。
  • Groovy 允许定义简单脚本,同时无需定义正规的 class 对象。
  • Groovy 在普通的常用 Java 对象上增加了一些独特的方法和快捷方式,使得它们更容易使用。
  • 变量,属性,方法,闭包的参数以及方法的返回类型都是可有可无的。
  • Groovy 默认导入常用的包。

Groovy的生态圈已经很全面了。

  • Gradle,自动化构建工具,通过编写简单的Groovy脚本,便可进行依赖管理和项目构建。如果你想使用Android Studio进行Android开发,Gradle已经成为了Android Studio中的默认构建工具了。
  • Grails,一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring、Hibernate和其它标准Java框架之上,从而为大家带来一套能实现超高生产力的一站式框架。
  • Spock,测试框架,可通过其特有的DSL编写测试案例;
  • Griffon,Swing开发框架,其灵感来自于Grails。

Groovy是一个面向对象的脚本语言,跟Java还是有很大不同的,多了解一门语言,对于提高自己的综合编程能力也是大有裨益的。另外,如果你是一名Java软件工程师,学习Groovy几乎可以说是零成本的。既然有这么多好处,确实是时候来学习一下Groovy了。

Groovy注释

与Java的注释语法相同,如://注释 /* 注释 */ /** 注释 */ 都支持,唯一不同的是,Groovy支持像Shell脚本那样的首行附加注释

#!/usr/bin/env groovy

defx=1

...

“#!”注释只允许在脚本文件的第一行出现,通过这种方式 Unix shell能定位groovy 的启动脚本并且运行这些脚本。

Groovy变量

Groovy中定义变量默认的修饰符是public,变量定义时遵循Java变量命名规范,变量名以字母、下划线或美元符号$开始,可以包含字母、数字、下划线和美元符号$,但关键字除外。除了这些规则之外,Groovy定义变量时如果是一行定义一个类型,末尾的分号可以省略,但是如果多个变量占一行,变量之间必须以分号分割。

整形变量

整数类型与Java相同:byte、char、short、int、long、java.lang.BigInteger。

//基本数据类型

bytea=1

charb=2

shortc=3

intd=4

longe=5

intx=9;

intm=10;longn=11

//大整型

BigInteger bi=6

在Groovy中,上面的变量定义方式跟Java可以说没有太大的不同,但是Groovy中多了一个关键字def来定义变量。包括下面介绍的String类型的变量都可以使用def来定义。用def定义的变量时无类型的变量,这里所说的无类型的变量,并不表示该变量就不属于某一个类型了,def修饰变量正是Groovy为动态语言的标记,大概def修饰变量就相当于Java中Object来修饰变量吧。
如果通过使用def关键字使用可选类型,那么整数的类型将是可变的:它取决于这个类型实际包含的值。

defa=1

assertainstanceofInteger

//assert a instanceof Long//错误

defb=2147483648

assertbinstanceofLong

boolean变量的定义与整形类似,这里就不再介绍了。

字符变量

与Java不同,Groovy没有显式的字符文本,然而你可以通过三种不同方式,可以将Groovy字符串实际作为一个字符使用。

charc1='A'//(1)

assertc1 instanceofCharacter

def c2='B'aschar//(2)

assertc2 instanceofCharacter

def c3=(char)'C'//(3)

assertc3 instanceofCharacter
  1. 当定义变量时,通过指定char类型,使变量包含字符
  2. 通过as操作符使用类型强制转换
  3. 通过char操作符做类型转换

(1)定义时使用的是char类型直接限定的,而(2)(3)定义使用的是无类型def定义的。

字符串

字符串定义中,除了支持Java语法定义字符串,还提供了其它方式定义字符串,如单引号、三单引号、三双引号和插值字符串等。

def str="hello world"

def str01='hello world'

def str02='''hello world'''

def str03='hello'+'world'

def str04="""hello world"""

三单引号和三双引号字符串是多行的,你可以使字符串内容跨越行边界,不需要将字符串分割为一些片段,不需要连接,或换行转义符:

	
def multilineString='''line one

line two

line three'''

如果你的代码是缩进的,如类中的方法体,字符串将包括缩进的空格。转义字符的使用与Java相同。


'an escaped single quote: \' needs a backslash'

'an escaped escape character: \\ needs a double backslash'

插值字符串

任何Groovy表达式可以在所有字符文本进行插值,除了单引号和三单引号字符串。插值是使用占位符上的字符串计算值替换占位符的操作。占位符表达式是被${}包围,或前缀为$的表达式。

为$的表达式。

def name="admin"

def str="hello ${name}"

而且任何Groovy表达式是合法的,如下使用都是合法的。


def str="1 + 2 = ${1 + 2}"

assertstr=="1 + 2 = 3"

不仅任何表达式,实际上也允许${}占位符。语句也是被允许的,但一个语句等效于null。如果有多个语句插入占位符,那么最后一个语句应该返回一个有意义的值被插入占位符。例如,"The sum of 1 and 2 is equal to ${def a = 1; def b = 2; a + b}"字符串是被支持的,也能如预期一样工作,但一个好的实践是在GString占位符插入一个简单的表达式。

斜杠字符串

这里斜杠字符串跟JavaScript中斜杠字符串使用方式类似,使用/定义字符串,主要用于定义正则表达式和模式,这种方式在定义正则表达式的时候相当有用,因为在斜杠中包括的字符串不需要转义字符。

//Java中定义正则表达式

Stringregex="//.*hello world.*//";

//Groovy定义正则表达式

def regex=/.*hello world.*/

可以用正斜杠定义字符串,但是如果字符串本身就包含正斜杠,这时候就需要转义了。

def escapeSlash=/The character\/isaforward slash/

assertescapeSlash=='The character / is a forward slash'

同样斜杠字符串也是多行的并且支持插值。

	
def name="admin"

def str=/hello${name}/

字符串总结表

类型 表示方式 插值 多行 转义字符
单引号 '...' \
三单引号 '''...''' \
双引号 "..." \
三双引号 """...""" \
斜杠 /.../ \

数组

Groovy使用中括号[]来对数组进行初始化赋值,但是不持之Java中用大括号{}进行赋值,大括号在Groovy中会被认为是闭包的标记,闭包在下一篇文章中再做介绍。

//该种方式不支持

//String[] strs={"aaa","bbb","ccc"}

String[]array=["aaa","bbb","ccc"]

assertarrayinstanceofString[]

//创建字面量数组,需要通过类型转换或类型定义来定义数组类型。

def numAry=[1,2,3]asint[]

assertnumAry instanceofint[]

assertnumAry.size()==3

//创建包含不同类型的数组

String[]mulAry=["aaa",123,true]

//定义多维数组  指定数组为3*3

def matrix3=newInteger[3][3]

assertmatrix3.size()==3

//不指定数组大小

Integer[][]matrix2

matrix2=[[1,2],[3,4]]

assertmatrix2 instanceofInteger[][]

List列表

定义列表与数组不同之处在于在变量声明时不需要[],Groovy的列表是java.util.List,因为Groovy没有定义任何集合类。当定义一个列表常量时,默认的列表具体实现是java.util.ArrayList,除非你指定。

请大家注意,List定义时如果是通过字面量形式定义的,不可指定声明类型是int或者String,但是可以使用List、ArrayList或者LinkedList。

//正确

def nums01=[1,2,3]

assertnums01 instanceofList

assertnums01.size()==3

//错误

//int num02=[1,2,3]

//创建包含不同类型列表

def myList=["aaa",123,true]

List list=[1,2,3]

LinkedList list01=[1,2,3]

def list02=[1,2,3]asLinkedList

访问列表如访问数组类似,通过中括号[索引]的形式访问,但是索引可以为负值,负值从末尾往前,最后一个索引为-1。也可以使用范围[m..n]或者左移运算符

def list=[1,2,3,4]

assertlist[0]==1

assertlist[1]==2;

assertlist[-1]==4

assertlist[-2]==3

list[1]=100

assertlist[1]==100

list[4]=101

assertlist[4]==101

list<<102//此处是列表左移

assertlist[5]==102

assertlist[-1]==102

assertlist[0,2]==[1,3]

assertlist[0..2]==[1,100,3]

Map集合

在Groovy中称为映射,映射使键到值关联,使用冒号将键值分隔开,每个键值对使用逗号,整个键和值使用方括号包围。默认的映射实际上是java.util.LinkedHashMap类型的。

	
def maps=[one:100,two:101,three:102]

assertmaps['one']==100

assertmaps.one==100

maps['two']=1001

assertmaps['two']==1001

assertmaps instanceofjava.util.LinkedHashMap

在上述定义中one、two、three默认是字符串,所以当我们尝试使用maps[one]访问时会出错,但是如果所有的键都是统一并且可以转换为非String类型,这时候可以根据类型访问。

def maps=[1:100,2:101,3:102]

assertmaps[1]==100

//assert maps.1==100;//报错

在映射中键可以使用一个变量作为值,但是要注意必须加上圆括号包围这个变量或者表达式。

def key="name"

def person=[key:'admin']

assert!person.containsKey('name')

assertperson.containsKey('key')

//////////////////////////////////////////////////

def key="name"

def person=[(key):'admin']

assertperson.containsKey('name')

assert!person.containsKey('key')

接下来我们总结一下,如果定义一个空的数组、列表或者映射是什么样子的。

	
//字符串

String[]emptyStrs=[]

//或

def nums=[]asint[]

//列表

def emptyList=[]

//映射

def emptyMap=[:]

本篇文章主要介绍了Groovy的语法和变量的定义,有关函数和类可以参看下一篇文章Groovy进阶之函数、闭包和类

本文地址www.sunnyang.com/521.html

参考资料

《Groovy语言规范》-语法

Gradle for Android 第七篇( Groovy入门 )

Groovy基本语法(1)

Groovy学习笔记之块、闭包与函数

Groovy百度百科

Groovy 入门指南.pdf

精通 Groovy