Groovy学习笔记
一、灵活初始化与具名参数
Groovy中可以灵活的初始化一个JavaBean类。
在构造对象时,可以简单地以逗号分隔的名值对来给出属性值。如下:
class Person {
def age, gender
}
def student = new Person(age: 10, gender: '男')
printlen("age is: $student.age, gender is: $studnet.gender")
在以上代码中,没有定义构造器,编译器会默认提供一个无参构造器。如果定义了构造器,则编译器不再提供无参构造器。
如果代码中有定义构造器,则可直接以逗号分隔的值来给出属性值。如下:
class Person {
def age, gender
Person (age) {
this.age = age
}
Person (age, gender) {
this.age = age
this.gender = gender
}
}
def student = new Person(30)
println("student: age = $student.age")
def student2 = new Person(10, '男')
println("student2: age = $student2.age, gender = $studnet2.gender")
在以上代码中,定义了一个全参构造器。此时不能再简单地以逗号分隔的名值对来给出属性值。
这是因为在Groovy中,如果发送的实参的个数多于方法的形参的个数,而且多出的实参是名值对,那么Groovy会假设方法的第一个形参是一个Map,然后将实参列表中的所有名值对组织到一起,作为第一个形参的值。之后,再将剩下的实参按照给出的顺序赋给其余形参。如下:
def student3 = new Person(age: 10, gender: '男')
println("student3: age = $student3.age, gender = $student3.gender")
在以上代码中,实参个数为2,大于Person (age) {}
的形参个数。Groovy便假设age是一个Map类型的参数,将实参中的名值对组织到一起,作为age的值。故输出的结果如下:
student3: age = [age: 10, gender: 男], gender = null
再举个例子:
def student4 = new Person(age: 10, gender: '男', '男', height: '173cm')
println("student4: age = $student4.age, gender = $student4.gender")
输出结果如下:
student4: age = [age: 10, gender: 男, height: 173cm], gender = 男
在以上代码中,实参个数为4,大于Person (age, gender) {}
的形参个数。Groovy便又将实参中的名值对组织到一起,作为age的值。故height: 173cm
虽然位于参数中最后一个,但仍然被赋值给age。
尽管这种赋值灵活性很大,但是可读性较差,所以谨慎使用。如果想使用具名参数,那最好只接受一个Map形参,而不要混用不同的形参。
我们可以通过显示的将第一个形参指定为Map,可以避免这种混乱。如下:
Class House {
def location, area, price
def info(Map location, area, price) {
println("house: location = $location, area = $area, price = $price")
}
}
在以上代码中,如果实参包含的不是两个对象加至少一个名值对,代码就会报错。
二、可选形参
Groovy中可以把方法和构造器的形参设为可选的。
要定义可选形参,只需要在形参列表中给它赋上一个值。如下:
def log(x, base = 10) {
Math.log(x) / Math.log(base)
}
println log(1024)
println log(1024, 10)
println log(1024, 2)
在以上代码中,第一个输出结果没有赋base值,则base值为默认值为10。第二第三个输出结果赋有值,则base值为赋的值。
Groovy还会把末尾的数组形参视作可选的,可以为最后一个形参提供零个或多个值。如下:
def task(name, String[] details) {
println "$name - $details"
}
task('Call', '123')
task('Call', '123', '456')
task('Check Mail')
输出如下:
Call - [123]
Call - [123, 456]
Check Mail - []
三、使用多赋值
Groovy支持多赋值,我们可以将多个变量以逗号分隔,放在圆括号中,置于赋值表达式左侧即可。如下:
def splitName(fullName) {
fullName.split(' ')
}
def (firstName, lastName) = splitName('James Bond')
println "$lastName, $firstName $lastName"
输出如下:
Bond, James Bond
除此之外,还可以使用该特性来交换变量,无需创建中间变量来保存被交换的值。只需要将欲交换的变量放在圆括号内,置于赋值表达式左侧,同时将它们以相反顺序放于方括号内,置于右侧即可。如下:
def name1 = "Tom"
def name2 = "Jerry"
(name1, name2) = [name2, name1]
当变量与值数目不匹配时,Groovy亦可自动处理。如果有多余的变量,Groovy会将它们为null,多余的值则会被丢弃。但是,如果多余的变量是不能设置为null的基本类型,Groovy将抛出一个异常。