Groovy的named parameter

Groovy的named parameter 一般有两个用途:

1. 用在groovybean的构造函数中,提供一种便利的方式来创建新对象。

2. 用在方法中(static or not-static),如果传入的参数是named parameter的话,那么该方法会自动收集这些named parameter,然后当成该方法的第一个参数。

 

我们先来看看第一种用途,假设我们有下面的groovybean:

 

 

class Person { 
         String name
         int age 
}

 

 

那么groovy会自动的为这个groovybean生成一个带map为参数的构造函数,类似于下面:

 

 

class Person {
	String name
	int age
	Person(Map map) { map.each {k,v->
			this."${k}"=v
		}
	}
}

 

 

 

那么我们在创建Person对象的时候,可以通过如下方式来进行:

 

 

class TestMain { 
	
	static main(args) { 
		def p =new Person([name:'yezi',age:25]) 
		println p.name 
		println p.age
	}
}

 

 

实际上下面这两句是等价的:

 

 

def p =new Person([name:'yezi',age:25]) 
def p =new Person(name:'yezi',age:25)

 

方括号是可选的。

 

如果你使用过SPRING的dataBinder来讲HttpServletRequest的参数直接绑定成对象的话,那么就会发现我们也可以通过这个特性来完成spring dataBinder的这个feature。

 

 

def httpReq=... 
httpReq.setAttribute("name","yezi") 
httpReq.setAttribute("age",25)

def p = new Person(httpReq.getParams)

 

接下来让我们看看第二种用法,我们定义了printlnSth方法:

 

 

class Person {
	String name 
	int age 
	void printlnSth(def params, def otherParams) { 
		println params.name 
		println params.age 
		println otherParams
	}
}

 

 

 

 然后我们按照下面的方式来进行调用:

 

 

class TestMain { 
	static main(args) { 
		def p =new Person([name:'yezi',age:25]) 
		p.printlnSth name:"tianzi", "i am other params", age:25 
		p.printlnSth "i am other params", age:25,name:"tianzi"
	}
} 

 

 

//输出:

tianzi

25

i am other params tianzi

25

i am other params

 

从上可以看到,如果一个方法传入的参数包含named parameter的话,那么groovy就会自动收集传入的所有named parameter, 然后当作该方法的第一个参数传进去,而不理会named paramter的位置。 但是我们同时也注意到,在定义printlnSth方法的时候,我们都是没有指定参数的类型的(都通过def指定),如果我们直接显式指定printlnSth的第一个参数的类型呢? 比如说指定为map, 如:

 

 

class Person { 
	String name 
	int age 
	void printlnSth(Map params, def otherParams) { 
		println params.name 
		println params.age 
		println otherParams
	}
}

 

 

 

  然后运行TestMain, 发现结果是一样的。

那如果显示指定printlnSth的第一个参数类型为Map之外的类型呢?让我们修改为List后来看看。

 

 

class Person { 
	String name 
	int age 
	void printlnSth(List params, def otherParams) { 
		println params.name 
		println params.age 
		println otherParams
	}
}

 

 

  然后再次运行TestMain, 这个时候groovy提示错误了,

Caught: groovy.lang.MissingMethodException: No signature of method: com.yezi.test.Person.printlnSth() is applicable for argument types: (java.util.LinkedHashMap, java.lang.String) values: [[name:tianzi, age:25], i am other params]

 

从这个错误信息我们可以推断中,如果一个方法,它的传入参数含有named parameter的话,那么groovy就会自动去寻找第一个参数为map的方法来执行(可能方法有重载)。

 

那么第二种用法一般做什么用呢, 一般是应用于DSL的编写中,假设我们要实现一个方法, 用来表示从哪里开车多少公里到哪里, 那么一般我们会这么定义方法:

 

 

class TestMain { 
	static main(args) { 
		drive(10,"1130 kifer rd","sfo")
	}
	
	static void drive(miles,origin,destination) {
		println "drive ${miles} miles from ${origin} to ${destination}"
	}
} 

 

但是这样对于不是程序员的业务人员来说是不直观的。但是如果我们定义成下面这样的话:

 

 

class TestMain { 
	static main(args) { 
		drive(10,from:"1130 kifer rd",to:"sfo")
	}
	
	
	static void drive(addrInfo,miles) {
		println "drive ${miles} miles from ${addrInfo.from} to ${addrInfo.to}"
	}
} 

 

这样的话,对于业务人员来讲,他也可以写,同时方法调用会显得更加清晰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值