Function和Closure的区别


Groovy中,function和closure非常相似,不过还是有区别,通过示例来说明。

1)函数体内不能访问上下文中通过def定义的变量
a = 32 //def keyword not used for this one, 这个变量可以在下面的函数中访问到
def c = 'there', d = 'yonder'
def f(){
  assert a == 32 //outer 'a' visible because 'def' keyword wasn't used with it
  def c = 'here'
    //compiles OK because other defined c invisible inside function definition
  //println d //a compile error when uncommented: d not accessable
  c
}
assert f() == 'here' //syntax to invoke a function

2)定义函数的时候,def关键字不能省略。

def f(){
  a = 1
  c = { 'here, again' }
  c()
}
assert f() == 'here, again'
//g(){ println 'there, again' }
    //a compile error when uncommented: def keyword required
 
注:也可以把一个函数定义赋值给另一个函数名:

def f(){ 77 } //define function using name 'f'
assert f() == 77
def g = this.&f //special syntax to assign function to another variable
assert g() == 77
def h = g //don't use special syntax here
assert h() == 77
f = 'something else' //this 'f' is a VARIABLE, not the function NAME
assert f() == 77 //the function name can't be reassigned

3)函数定义不能嵌套,即一个函数或块中,不能进行函数定义。

def f(){
  //def g1(){ println 'there' }
      //a compile error when uncommented: can't nest functions
  'here'
}
assert f() == 'here'
try{
  //def g2(){ println 'yonder' }
      //a compile error when uncommented: can't nest functions
}
c = {
  //def g3(){ println 'outer space' }
      //a compile error when uncommented: can't nest functions
}
def h(){
  try{ def c = { 'here, again' } }
      //we can have blocks and closures within functions
}

4)函数参数方面,函数同样可以有参数,但与Closure略有不同,函数参数能力更强些:

def foo( list, value ){
  list << value
}
x = []
foo(x, 1)
foo(x, 2)
assert x == [1, 2]

函数可以做到多态定义,即用一个名字,不同的参数,来定义不同的函数。

def foo(value){ 'v1' }
def foo(list, value){ 'v2' }
assert foo(9) == 'v1'
assert foo([], 1) == 'v2'

函数返回值和Closure类似,不过通过void前缀来定义的函数,返回总是null

def f1(){ 7 }
assert f1() == 7 //value of last statement is returned

def f2(){ return 8; 3 }
assert f2() == 8 //return explicitly using return

void f3(){ 10 }
assert f3() == null //null always returned

//void f4(){ return 9 }
      //a compile error when uncommented: can't use 'return' in a void function

5)函数名字优先于Closeure变量名字。
  
def c(){'method c'}
def c= {-> 'closure c'}
assert c() == 'method c'

def d(i){'method d'}
def d= {'closure d'}
assert d(9) == 'method d'

6)和Closures类似,当参数是closure时,函数调用也可以采用直观的简写形式:

def f(Closure c){ c() }
assert f{ 'heehee' } == 'heehee'

7)函数的参数可以支持缺省值,当然仅限于后面的参数

def dd( a, b=2 ){ "$a, $b" }
assert dd( 7, 4 ) == '7, 4'
assert dd( 9 ) == '9, 2'

8)函数的参数可以实现命名传递,注意总是使用第一个参数,作为map
def f(m, i, j){ i + j + m.x + m.y }
assert f(6,x:4, y:3,7) == 20

def g(m, i, j, k, c){ c(i + j + k, m.x + m.y) }
assert g(y:5, 1, 2, x:6, 3){a,b-> a * b } == 66

7)函数可以通过最后一个参数Object[] 来支持动态参数

def c( arg, Object[] extras ){
  def list= []
  list<< arg
  extras.each{ list<< it }
  list
}
assert c( 1 )          == [ 1 ]
assert c( 1, 2, 3, 4 ) == [ 1, 2, 3, 4 ]

8)函数对于List类型的参数,也进行了特殊关照,可以自动拆开来使用

def x(a, b, c){a + b + c}
def list=[1,2,3]
assert x(list) == 6

9)函数可以递归调用

def gcd( m, n ){ if( m%n == 0 )return n; gcd(n,m%n) }
assert gcd( 28, 35 ) == 7

概括起来,Closeure更加直观灵活,而函数功能更规范,相对功能更强些。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值