2.4 灵活初始化与具名参数

  1. Groovy 中可以灵活地初始化一个 JavaBean 类。在构造对象是,可以简单地以逗号分割的名值对来给出属性值。如果类有一个无参构造器,该操作会在构造器之后执行。也可以定义自己的方法,使其接受具名参数。要利用这一特性,需要把第一个形参定义为 Map。

  2. 举个栗子:

class Robot {
    def type, height, width

    def access(location, weight, fragile) {
        println "Received fragile? $fragile,weigth: $weight, loc: $location"
    }
}

robot = new Robot(type: "arm", width: 10, height: 40)
println "$robot.type, $robot.height, $robot.width"

robot.access(10, 50, true)
robot.access(x:30, y:20, z:10, 50, true)
robot.access(50, true, x:300, y:200)

打印结果:

arm, 40, 10
Received fragile? true,weigth: 50, loc: 10
Received fragile? true,weigth: 50, loc: [x:30, y:20, z:10]
Received fragile? true,weigth: 50, loc: [x:300, y:200]
  1. 根据第一行打印结果,Groovy 创建了灵活的构造器,把 type、height 和 width 等实参当作了名值对。

  2. 根据后面三行的打印,如果方法的实参个数多余形参个数,而且多出的实参是名值对,那么 Groovy 会把方法的第一个形参假设为一个 Map,然后将实参列表中的所有名值对组织到一起,作为第一个形参的值。之后,再将剩下的实参按照给出的顺序赋值给其余参数。

  3. 尽管在上面的例子中,这种灵活性非常强大,但是可能会给人带来困惑,所以请谨慎使用。如果想使用具名参数,那最好只接受一个 Map 形参,而不要混用不同的类型。在上面的例子中,如果传递的是3个整型实参,该特性会导致一个问题。这种情况下,编译器将会按照顺序传递实参,而不会从这些实参创建一个 Map,因此结果就和预想的不同了。通过显式地将第一个形参指定为 Map,可以避免这种混乱:

def access(Map location, weight, fragile) {
        println "Received fragile? $fragile,weigth: $weight, loc: $location"
}

你可能感兴趣的:(2.4 灵活初始化与具名参数)