前言
刚学习Groovy时,我感觉Groovy的语法太随意了使人摸不着头脑,不过看完官方的语法介绍,总算摸着了一些门道。不过相对于Java显得太琐碎了。这着实让人很头疼。因此写这篇日记,来记录Groovy的点滴琐碎,以及一些自己的心得体会。本博客的不同于其他中文文档之处的是,我在亲自试验的基础上总结而来。不同于按照英文单词对照翻译。很大一部分是自己的想法,如有不当之处,还请批评指正!O(∩_∩)O谢谢
这篇文章的知识来源于两方面:一方面是官方文档;一方面是网络教程;
知识来源:
1. Groovy官方知识库: Groovy官方知识库
关于Groovy官方知识库,我找到了一个中文版,不过翻译的不全,同样还是感谢作者的辛勤劳动。Groovy官方知识库中文版
2. 网络教程:
语法
语法syntax官方规范
《Groovy语言规范》-语法中文版
1. 注释
这部分和Java没有区别。不再赘述。
2.关键字
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 | - | - | - |
3. 标识符
3.1 普通标识符
Groovy关于标识符的规范与Java差不错。不过有一点需要指出的是:
当关键字前跟有点(.)作为标识符时是有效的。例如:
foo.as
foo.assert
foo.break
foo.case
foo.catch
至于应有,现在举个例子:
def person=[as: “dabao”] //这是一个map集合。稍后会介绍。
println person.as; //在这里引用as,其作为标识符是有效的。
3.2 标识符的引用
标识符的引用是通过点号+标识符。引用方式有多种,不过有一条原则,即点号后只要是字符串(字符串的表示方式有很多)或者没有引号都可以:
person.name或者 person.”name” 或者person.’name’.
举个例子:
def map = [:] map."an identifier with a space and double quotes" = "ALLOWED" map.'with-dash-signs-and-single-quotes' = "ALLOWED" assert map."an identifier with a space and double quotes" == "ALLOWED" assert map.'with-dash-signs-and-single-quotes' == "ALLOWED"
或者:
map.'single quote' map."double quote" map.'''triple single quote''' map."""triple double quote""" map./slashy string/ map.$/dollar slashy string/$
甚至带有插入值的字符串都是可以的,例如:
def firstname = "Homer" map."Simson-${firstname}" = "Homer Simson" assert map.'Simson-Homer' == "Homer Simson"
4.字符串
初识Groovy的字符串会使人迷惑,不过仔细理解一下还是很有道理的,字符串是本文的重点,理解为要!
Groovy允许你实例化java.lang.String也允许你实例化groovy.lang.GString,后者在其他语言中通常被称作插值字符串。现在不懂插值字符串没关系,稍后见的多了就懂了。
4.1. 单引号字符串Single quoted string
Single quoted strings are a series of characters surrounded by single quotes:
单引号字符串是被单引号包裹起来的字符串:
'a single quoted string'
单引号字符串是 java.lang.String,不支持插值。
4.2. 拼接字符串String concatenation
在Groovy中所有的字符串都支持拼接,通过加号:
assert 'ab' == 'a' + 'b'
4.3.三个单引号括起来的字符串 Triple single quoted string
三个单引号括起来的字符串是两端分别被三个单引号括起来的字符串:
'''a triple single quoted string'''
三个单引号括起来的字符串 是java.lang.String,不支持插值。
三个单引号括起来的字符串可以跨行,不需要连接,或换行转义符:
def aMultilinestring = '''line one line two line three'''
注意:在每一行的末尾添加分隔符\会忽略换行例如:
def strippedFirstNewline = '''\ line one line two line three '''
4.3.1.转义特殊字符Escaping special characters
例如:单引号双引号…..使用\转移,防止阻断。
'an escaped single quote: \' needs a backslash' 'an escaped escape character: \\ needs a double backslash'
Some special characters also use the backslash as escape character:
例如:’\t’ 代表制表符,其他的不再一一列举,可以去官网查看。
4.3.2.Unicode转义字符传 Unicode escape sequence
例如:
'The Euro currency symbol: \u20AC'
4.4. 双引号字符串Double quoted string
"a double quoted string"
如果没有插值表达式,双引号字符串是普通的java.lang.String,如果插值存在则是groocy.lang.GString实例。
4.4.1. 字符串插值String interpolation
重点来了,这才是GString不同于java.lang.String的地方
def name = 'Guillaume' // a plain string def greeting = "Hello ${name}" assert greeting.toString() == 'Hello Guillaume'
也支持数学表达式:
def sum = "The sum of 2 and 3 equals ${2 + 3}" assert sum.toString() == 'The sum of 2 and 3 equals 5'
表达式必须要带大括号,至于标识符可以不带大括号,但是该标识符后面不可以紧跟其他字符或者是结尾。如下也是可行的:
def name = 'Guillaume' // a plain string def greeting = "Hello $name" assert greeting.toString() == 'Hello Guillaume'
同样美元符号$也是可以转义的。
4.4.2.插入闭包表达式的特殊例子 Special case of interpolating closure expressions
至于什么是闭包,以后会涉及。如果觉得难以理解这一小节可以先跳过。
至今,我们看到可以将任意的表达式插入
def sParameterLessClosure = "1 + 2 == ${-> 3}" //① assert sParameterLessClosure == '1 + 2 == 3' def sOneParamClosure = "1 + 2 == ${ w -> w###4.4.3. 与Java的互操作性Interoperability with Java### 当一个方法(无论是在Java或是Groovy中实现)预期需要一个java.lang.String,而我们传递了一个groovy.lang.GString实例,GString的toString()方法将会被自动调用。这个应该不难理解。我感觉称不上是一个特性。
String takeString(String message) { assert message instanceof String return message } def message = "The message is ${'hello'}" assert message instanceof GString def result = takeString(message) assert result instanceof String assert result == 'The message is hello'####4.4.4. GString和String的哈希值GString and String hashCodes#### 尽管插入值字符串(GString)可以被当做普通Java字符串使用,但它们依然是不同的字符串,特别表现在:它们的哈希值不同。普通Java字符串的哈希值是不变的,但GString却是可变的,GString的哈希值依赖于他的插入值。即使是同样值的字符串,GString和String的哈希值衣然不同。
assert "one: ${1}".hashCode() != "one: 1".hashCode()
GString and Strings having different hashCode values,using GString as Map keys should be avoided,especially if we try to retrieve an associated value with a String instead of a GString.
GString 和 String具有不同的哈希值,应该避免使用GString作为Map集合的键,特别是如果我们试图使用String代替GString作为键来获取值的时候。 def key = “a”
def m = [“${key}": "letter ${key}”]
assert m[“a”] == null
4.5. 三个双引号的字符串Triple double quoted string
Triple double quoted strings behave like double quoted strings,with the addition that they are multiline,like the triple single quoted strings.
三个双引号,两个双引号,三个单引号的字符串都支持跨行。
def name = 'Groovy' def template = """ Dear Mr ${name},You're the winner of the lottery! Yours sincerly,Dave """ assert template.toString().contains('Groovy') Neither double quotes nor single quotes need be escaped in triple double quoted strings. 无论双引号字符串还是单引号字符串在三个单引号的字符串中都需要被转义。##4.6. 斜杠字符串Slashy string## 斜杠分正斜杠( forward slash '/' )和反斜杠( backslash '\') 引自:[百度百科-斜杠](http://baike.baidu.com/view/1463371.htm) Beyond the usual quoted strings,Groovy offers slashy strings,which use / as delimiters. Slashy strings are particularly useful for defining regular expressions and patterns,as there is no need to escape backslashes. 除了一些平常的引号字符串之外,Groovy提供了正斜杠字符串,使用/作为分隔符。正斜杠字符串在定义正则表达式和pattern是特别有用,这时将不需要反斜线。
def fooPattern = /.*foo.*/ assert fooPattern == '.*foo.*'
仅仅正斜杠需要使用反斜杠转义: def escapeSlash = /The character \/ is a forward slash/
assert escapeSlash == 'The character / is a forward slash'
正斜线字符串支持跨行,也支持插入值例如: def multilineslashy = /one
two
three/
assert multilineslashy.contains('\n')
插入值: def color = 'blue'
def interpolatedSlashy = /a ${color} car/
assert interpolatedSlashy == 'a blue car'
有一点需要注意的是:
对于空字符串不能使用正斜杠字符串表示,原因是这样会被解释为注释。
4.7. 美元符号和正斜杠字符串 Dollar slashy string
Dollar slashy strings are multiline GStrings delimited with an opening
美元符号正斜杠字符串是可以跨行的GString字符串,使用$/分隔符开始,使用/$分隔符结束。这种字符串的转义字符是美元符,它能转义另一个美元符,或一个正斜杠。但是美元符和正斜线不用被转义(但也可以转义),反斜线更不需要被转义了(其自身就是转义字符),除了转义像GString占位符序列开始的字符串序列的美元符,或者$/需要转移。
上面的翻译太罗嗦,总之一句话:$或/转不转义都行,\ 无法被转义,\ $ 必须被转义。
示例如下: def name = “Guillaume”
def date = “April,1st”
def dollarslashy = $/
Hello $name,
today we’re ${date}.
$ dollar sign
$$ escaped dollar sign
\ backslash
/ forward slash
$/ escaped forward slash
$/$ escaped dollar slashy string delimiter
/$
assert [
‘Guillaume’,
‘April,1st’,
‘$ dollar sign’,
‘$ escaped dollar sign’,
‘\ backslash’,
‘/ forward slash’,
‘$/ escaped forward slash’,
‘/$ escaped dollar slashy string delimiter’
].each { dollarslashy.contains(it) }
4.8. 字符串总结表String summary table
String name | String Syntax | Interpolated | Multiline | Escape character |
---|---|---|---|---|
Single quoted | ‘…’ | \ | ||
Triple single quoted | ”’…”’ | √ | \ | |
Double quoted | “…” | √ | \ | |
Triple double quoted | “”“…”“” | √ | √ | \ |
slashy | /…/ | √ | √ | \ |
Dollar slashy |
|
√ | √ | $ |
4.9. 字符Characters
与Java不同,Groovy没有显式的字符文本,然而你可以通过三种不同方式,可以将Groovy字符串实际作为一个字符使用。 char c1 = ‘A’ //(1)当定义变量时,通过指定char类型,使变量包含字符
assert c1 instanceof Character //(2)通过as操作符使用类型强制转换
def c2 = ‘B’ as char //
assert c2 instanceof Character
def c3 = (char)’C’ //(3)通过char操作符做类型转换
assert c3 instanceof Character
5. 数值型Numbers
Groovy支持不同类型的整数和小数,通常以Java的Number类型返回。
5.1. 整数值Integral literals
The integral literal types are the same as in Java:
整数类型和Java相同。
- byte
- char
- short
- int
- long
- java.lang.BigInteger
你可以创建这些类型的整数值,通过以下声明形式: // primitive types基本类型
byte b = 1
char c = 2
short s = 3
int i = 4
long l = 5
// infinite precision无穷大
BigInteger bi = 6
如果你通过使用def关键字使用可选类型,那么整数的类型将是可变的:它取决于这个类型实际包含的值。
对于正数: def a = 1
assert a instanceof Integer
// Integer.MAX_VALUE
def b = 2147483647
assert b instanceof Integer
// Integer.MAX_VALUE + 1
def c = 2147483648
assert c instanceof Long
// Long.MAX_VALUE
def d = 9223372036854775807
assert d instanceof Long
// Long.MAX_VALUE + 1
def e = 9223372036854775808
assert e instanceof BigInteger
同样,对于负数: def na = -1
assert na instanceof Integer
// Integer.MIN_VALUE
def nb = -2147483648
assert nb instanceof Integer
// Integer.MIN_VALUE - 1
def nc = -2147483649
assert nc instanceof Long
// Long.MIN_VALUE
def nd = -9223372036854775808
assert nd instanceof Long
// Long.MIN_VALUE - 1
def ne = -9223372036854775809
assert ne instanceof BigInteger
5.1.1.可选择的非十进制表示 Alternative non-base 10 representations
二进制数Binary literal
在Java6之前,和在Groovy中一样,数字只能使用十进制,八进制和十六进制表示.使用Java7和Groovy2你能使用0b前缀作为一个二进制符号:
int xInt = 0b10101111 assert xInt == 175 short xShort = 0b11001001 assert xShort == 201 as short byte xByte = 0b11 assert xByte == 3 as byte long xLong = 0b101101101101 assert xLong == 2925l BigInteger xBigInteger = 0b111100100001 assert xBigInteger == 3873g int xNegativeInt = -0b10101111 assert xNegativeInt == -175
八进制Octal literal
在Java6之前,数字只能使用十进制,八进制和十六进制表示.使用Java7和Groovy2你能使用0后面跟八进制数的典型格式表示。
int xInt = 077 assert xInt == 63 short xShort = 011 assert xShort == 9 as short byte xByte = 032 assert xByte == 26 as byte long xLong = 0246 assert xLong == 166l BigInteger xBigInteger = 01111 assert xBigInteger == 585g int xNegativeInt = -077 assert xNegativeInt == -63
十六进制Hexadecimal literal
十六进制数以ox开头
int xInt = 0x77 assert xInt == 119 short xShort = 0xaa assert xShort == 170 as short byte xByte = 0x3a assert xByte == 58 as byte long xLong = 0xffff assert xLong == 65535l BigInteger xBigInteger = 0xaaaa assert xBigInteger == 43690g Double xDouble = new Double('0x1.0p0') assert xDouble == 1.0d int xNegativeInt = -0x77 assert xNegativeInt == -119
5.2. 小数Decimal literals
小数类型同Java中一样:
- float
- double
- java.lang.BigDecimal
You can create decimal numbers of those types with the following declarations:
你可以创建这些类型的小数通过以下声明:
// primitive types float f = 1.234 double d = 2.345 // infinite precision BigDecimal bd = 3.456
Decimals can use exponents,with the e or E exponent letter,followed by an optional sign,and a integral number representing the exponent:
小数可以用指数,使用e或者E指数字母,紧跟着一个可选符号,且有一个整数表示指数:
assert 1e3 == 1_000.0 assert 2E4 == 20_000.0 assert 3e+1 == 30.0 assert 4E-2 == 0.04 assert 5e-1 == 0.5
注意: 1_000.0的下划线有没有都可以,后续会介绍。
为了精确的进行小数计算,Groovy选择java.lang.BigDecimal作为小数类型。此外,float和double也被支持,但要求有一个显式类型定义,类型转换或后缀。即使BigDecimal是默认的小数,使用float或double作为类型参数的方法或闭包也可以接受这些数值。[这一段翻译的不错,摘抄过来]
小数不能使用二进制,八进制和十六进制表示。
5.3. 带下划线的值Underscore in literals
When writing long literal numbers,it’s harder on the eye to figure out how some numbers are grouped together,for example with groups of thousands,of words,etc. By allowing you to place underscore in number literals,it’s easier to spot those groups:
在书写较大的数值时,肉眼很难辨别这个大数是由多少个数字组成的。通过使用下划线在数值表示中,这变得相对容易了一些。
long creditCardNumber = 1234_5678_9012_3456L long socialSecurityNumbers = 999_99_9999L double monetaryAmount = 12_345_132.12 long hexBytes = 0xFF_EC_DE_5E long hexWords = 0xFFEC_DE5E long maxLong = 0x7fff_ffff_ffff_ffffL long alsoMaxLong = 9_223_372_036_854_775_807L long bytes = 0b11010010_01101001_10010100_10010010
另外值得一提的是:下划线的位置,由你定。不是固定的。
5.4.数值类型后缀Number type suffixes
我们可以强制一个数(包括二进制,八进制,和十六进制)表示指定类型通过添加后缀的方式,后缀可以大写也可以小写。
Type | Suffix |
---|---|
BigInteger | G or g |
Long | L or l |
Integer | I or i |
BigDecimal | G or g |
Double | D or d |
Float | F or f |
例子:
assert 42I == new Integer('42') assert 42i == new Integer('42') // lowercase i more readable assert 123L == new Long("123") // uppercase L more readable assert 2147483648 == new Long('2147483648') // Long type used,value too large for an Integer assert 456G == new BigInteger('456') assert 456g == new BigInteger('456') assert 123.45 == new BigDecimal('123.45') // default BigDecimal type used assert 1.200065D == new Double('1.200065') assert 1.234F == new Float('1.234') assert 1.23E23D == new Double('1.23E23') assert 0b1111L.class == Long // binary assert 0xFFi.class == Integer // hexadecimal assert 034G.class == BigInteger // octal
5.5.数学运算符 Math operations
尽管关于操作符的介绍后续还会有专门介绍,但是讨论数学操作符的使用和运算后结果的类型仍然是重要的。
Division and power binary operations aside (covered below),
除法和幂二元运算稍后刊出。
1. byte char short和int进行二元操作的结果是int
2. 使用long与byte char short int进行二元操作的结果是long
3. 使用BigInteger与任意其他整数类型进行二元操作结果是BigInteger
4. float double与BigDecimal进行二元运算的结果是double
5. 两个BigDecimal进行二元运算的结果是BigDecimal
6. 自身之间的二元运算结果还是自身的类型
具体参照官方发布的那个表,这里不再赘述
由于Groovy操作符重载,BigInteger与BigDecimal通常也能进行运算操作,与Java不同,在Java中你不得不明确的使用方法操作这些数字。
5.5.1. 除以操作的类型The case of the division operator
如果任何一个操作数是float或double,那么除法运算符/(和/= 用于除法和赋值)产生double结果,否则(当两个操作数是一个与整型类型short,char,byte,int,long,BigInteger or BigDecimal的任意组合)是一个BigDecimal结果。
BigDecimal division is performed with the divide() method if the division is exact (i.e. yielding a result that can be represented within the bounds of the same precision and scale),or using a MathContext with a precision of the maximum of the two operands’ precision plus an extra precision of 10,and a scale of the maximum of 10 and the maximum of the operands’ scale.这一段没看懂
**注:**For integer division like in Java,you should use the intdiv() method,as Groovy doesn’t provide a dedicated integer division operator symbol.
对于整数相除,在java中很简单比如4/3=1;但是在Groovy中没有提供这样的符号,你需要使用intdiv()方法来实现此功能。
int a=4; int b=3; assert a.intdiv(b) == 1;
5.5.2. 幂的运算类型The case of the power operator
直接贴出来例子:
// base and exponent are ints and the result can be represented by an Integer assert 2 ** 3 instanceof Integer // 8 assert 10 ** 9 instanceof Integer // 1_000_000_000 // the base is a long,so fit the result in a Long // (although it Could have fit in an Integer) assert 5L ** 2 instanceof Long // 25 // the result can't be represented as an Integer or Long,so return a BigInteger assert 100 ** 10 instanceof BigInteger // 10e20 assert 1234 ** 123 instanceof BigInteger // 170515806212727042875... // the base is a BigDecimal and the exponent a negative int // but the result can be represented as an Integer assert 0.5 ** -2 instanceof Integer // 4 // the base is an int,and the exponent a negative float // but again,the result can be represented as an Integer assert 1 ** -0.3f instanceof Integer // 1 // the base is an int,and the exponent a negative int // but the result will be calculated as a Double // (both base and exponent are actually converted to doubles) assert 10 ** -1 instanceof Double // 0.1 // the base is a BigDecimal,and the exponent is an int,so return a BigDecimal assert 1.2 ** 10 instanceof BigDecimal // 6.1917364224 // the base is a float or double,and the exponent is an int // but the result can only be represented as a Double value assert 3.4f ** 5 instanceof Double // 454.35430372146965 assert 5.6d ** 2 instanceof Double // 31.359999999999996 // the exponent is a decimal value // and the result can only be represented as a Double value assert 7.8 ** 1.9 instanceof Double // 49.542708423868476 assert 2 ** 0.1f instanceof Double // 1.07177346364329
6. 布尔值Booleans
Boolean values can be stored in variables,assigned into fields,just like any other data type:
布尔值可以被存储在变量中,赋值给字段,就像其他数据类型一样。
例子:
def myBooleanVariable = true boolean untypedBooleanVar = false booleanField = true
看到这里初学者可能会疑惑了booleanField是什么东西,它其实是一个字段,没有关键字def或者声明类型,说明它是一个字段。这在后续会有介绍。
7. List集合Lists
Groovy uses a comma-separated list of values,surrounded by square brackets,to denote lists. Groovy lists are plain JDK java.util.List,as Groovy doesn’t define its own collection classes. The concrete list implementation used when defining list literals are java.util.ArrayList by default,unless you decide to specify otherwise,as we shall see later on.
Groovy使用逗号分隔集合元素,并被中括号包括.Groovy集合就是普通JDK中的java.util.List,Groovy没有定义自己的集合类。具体的集合实现默认使用java.util.ArrayList,除非你指定类型,这在稍后将会介绍。
O(∩_∩)O哈哈~这段比较好翻译。 def numbers = [1,2,3]
assert numbers instanceof List
assert numbers.size() == 3
也可以创建包含不同类型元素的集合,例如:
def heterogeneous = [1,"a",true]
集合默认的是java.util.ArrayList我们也可以使用类型转换as,或者使用类型声明,举例如下:
def arrayList = [1,3] assert arrayList instanceof java.util.ArrayList def linkedList = [2,3,4] as LinkedList assert linkedList instanceof java.util.LinkedList LinkedList otherLinked = [3,4,5] assert otherLinked instanceof java.util.LinkedList
可以通过索引和[]来访问元素,索引可以是整数也可以是负数。使用<<可以向后追加。也可以使用缩略来访问部分元素。使用比较灵活,常用的访问方式如: def letters = [‘a’,‘b’,‘c’,‘d’]
assert letters[0] == ‘a’
assert letters[1] == ‘b’
assert letters[-1] == ‘d’
assert letters[-2] == ‘c’
letters[2] = ‘C’
assert letters[2] == ‘C’
letters << ‘e’
assert letters[ 4] == ‘e’
assert letters[-1] == ‘e’
assert letters[1,3] == [‘b’,‘d’]
assert letters[2..4] == [‘C’,‘d’,‘e’]
多维度集合: def multi = [[0,1],[2,3]]
assert multi[1][0] == 2
8. 数组Arrays
Groovy reuses the list notation for arrays,but to make such literals arrays,you need to explicitely define the type of the array through coercion or type declaration.
Groovy数组表示复用了集合的符号,创建数组还需要你去声明或者使用as强制类型转换。
例子如下: String[] arrStr = [‘Ananas’,‘Banana’,‘Kiwi’]
assert arrStr instanceof String[]
assert !(arrStr instanceof List)
def numArr = [1,3] as int[]
assert numArr instanceof int[]
assert numArr.size() == 3
同样你也可以创建多维度数组: def matrix3 = new Integer[3][3]
assert matrix3.size() == 3
Integer[][] matrix2
matrix2 = [[1,2],[3,4]]
assert matrix2 instanceof Integer[][]
Access to elements of an array follows the same notation as for lists:
访问数组的元素和集合访问元素没有区别: String[] names = [‘Cédric’,‘Guillaume’,‘Jochen’,‘Paul’]
assert names[0] == ‘Cédric’
names[2] = ‘Blackdrag’
assert names[2] == ‘Blackdrag’
注意:
Java’s array initializer notation is not supported by Groovy,as the curly braces can be misinterpreted with the notation of Groovy closures.
Java样式的数组初始化在Groovy是不支持的,因为花括号在会被误认为Groovy中的闭包。
9. Map集合Maps
Sometimes called dictionaries or associative arrays in other languages,Groovy features maps. Maps associate keys to values,separating keys and values with colons,and each key/value pairs with commas,and the whole keys and values surrounded by square brackets.
Map在中文中有映射的意思,一直用map集合,竟然忘记了他的中文意思。
在其他语言中有时被称作字典或者关联数组,在Groovy中称为映射。映射是的键和值建立了关联,使用冒号分隔键和值,键值对使用逗号隔开,所有的键值对使用方括号括起来就构成了map集合。 def colors = [red: ‘#FF0000’,green: ‘#00FF00’,blue: ‘#0000FF’]
assert colors[‘red’] == ‘#FF0000’
assert colors.green == ‘#00FF00’
colors[‘pink’] = ‘#FF00FF’
colors.yellow = ‘#FFFF00’
assert colors.pink == ‘#FF00FF’
assert colors[‘yellow’] == ‘#FFFF00’
assert colors instanceof java.util.LinkedHashMap
多说一句,使用中括号访问map集合的元素时,索引必须为字符串。使用点号则不用。
When using names for the keys,we actually define string keys in the map.Groovy creates maps that are actually instances of java.util.LinkedHashMap.
当使用名称作为键,我们实际上定义的是字符串作为映射的键。 Groovy创建映射,其实创建的是java.util.LinkedHashMap的实例。
如果你尝试访问一个map集合中没有显示的键,将会返回null:
assert colors.unkNown == null
In the examples above,we used string keys,but you can also use values of other types as keys:
在上面的例子中,我们使用字符串作为键,但你也可以使用其他类型的值作为键:
def numbers = [1: 'one',2: 'two'] assert numbers[1] == 'one'
Here,we used numbers as keys,as numbers can unambiguously be recognized as numbers,so Groovy will not create a string key like in our prevIoUs examples. But consider the case you want to pass a variable in lieu of the key,to have the value of that variable become the key:
这里,我们使用数值作为键,数字可以被明白无误的识别,所以Groovy将不会像之前的例子那样创建字符串类型的键。但是,想象一下这样的一个例子:你想要传递一个变量代替键,想要这个变量的值作为键:
这是重点 def key = ‘name’
def person = [key: ‘Guillaume’]
assert !person.containsKey(‘name’)
assert person.containsKey(‘key’)
如果你非要使用变量的值的话,你可以将这个变量用小括号括起来。 person = [(key): ‘Guillaume’]
assert person.containsKey(‘name’)
assert !person.containsKey(‘key’)
未完待续……………
Groovy备注:
1.初识Grovvy时你可能会感到疑惑,为什么Groovy里的函数可以直接用,比如println
反编译groovy源码生成的class文件你会发现你所创建的类继承自groovy.lang.Script,而在这个类中就有println方法,至于为什么方法的使用没有(),这其实是Groovy的特性。
2.Groovy自动导入如下包
groovy.lang.* groovy.util.* java.lang.* java.util.* javautil.regex.* java.net.* java.io.* java.math.BigDecimal java.math.BigInteger
介绍一些题外知识
1.groovy源码生成class字节码文件,并反编译
Groovy与Java是兼容的,但是怎样查看其转换后的Java源码呢?这里我从网上搜集到了一个方法:
第一步:使用命令将groovy文件转化成class文件
groovy -d 存放class文件的目录 **.gradle