`
wh870712
  • 浏览: 40299 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

groovy闭包和函数(转)

阅读更多
一、代码块
在代码块中用def关键字定义的变量不能在外部访问,如:

try{
  def msg="Hello,world!";
}
//pringln msg;

如果运行最后一行"println msg;",则会报错。

但是,在代码块中没有用def关键字声明的变量,就可以在外部访问,如:

try{
msg="Hello,world!";
}
println msg;

已经使用def定义的变量,不能再次用def定义:
def a=10;
//def a=20;


代码块是可以嵌套的:

try{
try{
  try{
   println "Hello,world!";
  }
}
}

二、闭包
闭包是可以引用外部上下文环境的一系列语句。可以将闭包赋予一个变量,并在稍后执行。

每个闭包都有一个返回值,默认的返回值就是该闭包中最后一行语句的结果

闭包可以访问外部的变量
def x=1;

def b={
x*2;//闭包可以访问外部的变量
}

将闭包赋予一个变量将记住该闭包创建时的上下文环境,即使运行时已经超出了原来的作用域:
def c;

try{
def m=10;
c={m};
}

println c();
在此处调用c(),即使已经超出了block的作用域,但仍能输出m的值


将一个闭包放入另一个闭包,可以创建它的两个实例:

c={e={"Hello,World";};e;}
v1=c();
v2=c();
println v1==v2//在此得出false,说明c()返回了不同的实例

可以在定义闭包时声明一些参数,之后在调用闭包时将这些参数值传入闭包:

c={n-> println "Parameter="+n;}

c(10);

可以利用参数将信息从包内导出,也就是所谓的“输出参数”

c={o,p-> o<<p};
x=[];
c(x,1);
c(x,2);
c(x,3);
println x;

在闭包中,总是可以用到一个叫做it的变量,如果没有显式的定义参数,则可以用it来引用

c={"Parameter=${it}"};
println c(10);

如果没有传入任何参数,it仍然存在,但是为null

闭包的参数不能使用作用域中已存在变量的名字,除了隐式变量it:
def it=10;

c={it*it};

println c(5);//在此,隐式变量it仍然引用参数5,而非外部定义的10

参数在调用闭包时可以被命名。这些被命名的参数将被组装进一个Map,并指定给闭包的第一个参数:
def x={a,b,c->a.m+a.n+a.o-b+c;};

println x(m:10,5,n:15,6,o:20);

在调用闭包x的时候,参数m:10,n:15,o:20被组装进Map赋予形参a,5、6按顺序分别赋予形参b和c,结果是46。

我们可以在闭包内部和外部查询参数的个数:


def c={a,b,c->getMaximumNumberOfParameters();}

println c(1,2,3);

println c.getMaximumNumberOfParameters();

调用闭包的时候,可以对最后的一个或几个参数应用默认值:

def c={a,b=2,c=3->a+b+c;};

println c(1);

结果输出6

一个闭包可以在最后一个参数前添加Object[]前缀来创建可变长度的参数:

def c={a,Object[] b->a+b[0]+b[1];}

println c(1,2,3);

我们可以使用一个list参数调用闭包。如果闭包没有定义一个list类型的参数,则此参数将作为分解的参数传入闭包:

def c={a,b,c->a+b+c};

println c([1,2,3]);

闭包可以通过将第一个或前几个参数固化为常量,使用curry方法进行拷贝:

def c={a,b,c->a+b+c};

def d=c.curry(1);//拷贝闭包c,并将第一个参数a固化为常量1

println d(2,3);//调用闭包d,只需要给出剩余的参数。实际使用的参数仍然是1,2,3

在闭包中,可以结合使用curry和不定长度参数:

def c={a,Object[] b->b.each({m->a=a+m;});a;};

def d=c.curry(1);

def e=d.curry(2,3);//实际参数为1,[2,3]

def f=e.curry(4);//实际参数为1,[2,3,4]

println f(5);//实际参数为1,[2,3,4,5]

闭包可以递归调用

三、函数

首先,必须使用def关键字定义函数,函数也不能嵌套使用;

其次,函数不能访问在外部通过def定义的变量:

def c=10;

def f(){
println c;//编译通过
}

//f();//运行时报错

还可以使用特殊的语法标记&将函数赋予新的命名:

def f(){
println "Hello,world!";
}

def s=this.&f;

s();

函数可以后参数,包括输入参数和输出参数;

如果两个函数的拥有不同个数的未指定类型的参数,则可以使用相同的名称

def f(a){
println a*a;
}

def f(a,b){
println a*b;
}

f(10);

f(5,10)

函数可以有返回值:
1.如果有显示地使用return关键字,则返回return指定的返回值,其后面的语句不再执行;
2.如果没有显式地使用return关键字,则返回函数最后一行语句的运行结果;
3.如果使用void关键字代替def关键字定义函数,则函数的返回值将为null。

如果一个函数与一个闭包拥有相同的名称和参数,则调用的时候将执行函数,而不是闭包:

def f(a){
return a*10;
}

def f={a->a*20};

println f(5);//输出50而不是100

函数可以接受闭包作为参数:

def f(a,Closure c){
c(a);
}

f(10){println "Parameter a = "+it;}

与闭包相同,函数可以为参数指定默认值:

def f(a,b=10){
return a+b;
}

println f(5);//输出15

函数也会将命名的参数包装进一个Map,并赋予第一个参数:

def f(a,b){
return b+a.x+a.y;
}

println f(x:2,1,y:3);//输出6

函数与闭包的相同之处还有,函数同样支持不定长度的参数、分解list作为参数,以及递归调用。

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    [Groovy入门]第五讲.将流程控制语句与方法重构为闭包

    闭包是Groovy中的一种函数对象,它可以捕获和存储其定义时的作用域内的变量,即使在闭包被传递或存储后仍然可以访问这些变量。闭包的特点在于它的“闭合”特性,即它能够记住并访问创建它的环境。在Groovy中,闭包...

    Groovy学习资料

    此外,Groovy还有闭包(Closure)的概念,这是Groovy强大的功能之一,它可以用来处理函数式编程任务,如数据过滤和映射。 其次,Groovy的动态特性是另一个关键知识点。Groovy可以在运行时改变类的结构,这意味着你...

    groovy入门实例代码详细(包括字符串,map,闭包等等)

    本入门实例代码详细地涵盖了Groovy的一些核心概念和常用特性,包括字符串操作、Map的使用以及闭包等。 1. **字符串操作**: - Groovy中的字符串可以是单引号或双引号包裹的。双引号中的变量可以直接展开,单引号则...

    Z2-Groovy in Action.pdf

    Groovy闭包可以像方法一样被调用,也可以作为参数传递给其他方法。闭包中可以自由地访问它被创建时作用域中的变量(闭包的自由变量)。这为Groovy的编程提供了很大的灵活性,例如可以轻松实现事件监听、回调函数、...

    fnz:Groovy的函数式编程思路

    在Groovy中,函数式编程的核心概念包括高阶函数、闭包、不可变数据结构和惰性计算。让我们逐一深入探讨这些概念: 1. **高阶函数**:高阶函数是可以接受一个或多个函数作为参数,或者返回一个函数的函数。Groovy中...

    groovy入门经典,groovyeclipse 插件

    Groovy的语法简洁,支持面向对象编程、函数式编程,并提供了许多现代语言特性,如闭包和动态类型。这使得Groovy成为快速开发、脚本编写以及构建自动化等任务的理想选择。 GroovyEclipse是一款强大的Eclipse插件,...

    Groovy Script 入门

    Groovy不仅支持传统的面向对象编程特性,还融合了函数式编程和元编程的特性,这使得Groovy脚本成为处理日常开发任务的强大工具。 #### 二、Groovy脚本的特点 1. **与Java的高度兼容性**:Groovy可以无缝地与Java...

    apache-groovy-sdk-3.0.6.zip

    7. **函数式编程支持**:Groovy支持闭包和高阶函数,这使得函数式编程风格在Groovy中变得非常自然,提高了代码的可读性和可维护性。 8. **动态和静态类型**:Groovy允许开发者在同一个项目中同时使用动态和静态类型...

    groovy in action 中文版 2017.11

    Groovy的闭包提供了非常强大的功能,比如高阶函数的能力,它们可以用来实现迭代、排序和其他集合操作。闭包的范围是指闭包访问变量的方式,包括外部变量和闭包内部定义的局部变量。 在实际使用中,Groovy的集合类型...

    groovy

    3. 支持闭包:Groovy中的闭包类似于函数引用,可作为参数传递,有助于实现函数式编程风格。 4. GString:类似于Java的字符串,但支持占位符表达式,使字符串操作更便捷。 5. 链式调用:对象属性和方法可以连续调用,...

    groovy-src-2.3.6.zip 最新稳定版源码

    3. **闭包和函数式编程**:Groovy支持闭包,这是一种强大的功能,可以作为函数传递或存储在变量中。2.3.6版本可能包含对闭包的优化和改进,这在处理集合和并发编程时尤其有用。 4. **动态类型和静态类型**:Groovy...

    apache-groovy-sdk-2.4.4

    4. **Groovy库**:SDK包含了完整的Groovy标准库,这些库提供了许多内置函数和类,覆盖了I/O、网络、XML处理、日期时间等多方面功能,极大地丰富了Groovy的生态系统。 5. **Ant任务**:对于使用Apache Ant构建系统的...

    Scala、Groovy++、Stackless Python、Erlang 学习笔记及分享

    Groovy的优点在于它支持闭包和元编程,使得代码更加简洁和可扩展。 Stackless Python是一种Python的变体,它强调微线程(microthreads)的使用,提供更高效的并发执行。Stackless Python通过减少每个线程的堆栈大小...

    apache-groovy-sdk-2.4.12.zip

    8. **闭包和函数式编程**:Groovy的一大特色是其强大的闭包支持,使得函数式编程风格在Groovy中成为可能。闭包可以作为参数传递,也可以用作返回值,极大地增强了代码的灵活性和可读性。 9. **元编程**:Groovy支持...

    apache-groovy-sdk-4.0.1下载

    - **闭包**:Groovy的闭包是强大的功能,可以用来实现函数式编程和回调机制,使得代码更加简洁和高效。 - **元编程**:Groovy允许在运行时修改类和对象的行为,这使得它非常适合构建框架和库,比如Grails web框架...

    groovy-docs-1.8.9.zip

    2. **闭包**:Groovy中的闭包类似于函数引用,可以作为参数传递,也可以存储在变量中。它们是Groovy强大的特性之一,1.8.9版本的文档会详细解释如何使用闭包进行函数式编程。 3. **GString**:Groovy的GString提供...

    某些必要的groovy

    3. **闭包(Closures)**:Groovy的闭包是其强大的特性之一,它类似于函数指针,可以作为参数传递,也可以作为返回值。闭包在处理集合操作、事件驱动编程或异步处理时非常有用。 4. **GroovyShell和...

    groovy用户指南--中文版

    - 这种特性使得闭包成为函数式编程的核心元素,增强了Groovy的灵活性和表达力。 总之,Groovy通过提供类定义、纯脚本、函数以及闭包等丰富的特性,为开发者提供了强大的工具集,既保持了与Java生态的紧密集成,又...

    Groovy in Action[文字版][中文]

    2. **闭包(Closure)**:Groovy中的闭包是其强大之处,它是一种可以捕获和存储上下文环境的函数。闭包可以作为参数传递,也可以作为返回值,这种特性使得Groovy非常适合进行函数式编程。 3. **元编程...

Global site tag (gtag.js) - Google Analytics