`
zeeeitch
  • 浏览: 83775 次
  • 性别: Icon_minigender_1
  • 来自: 九江
社区版块
存档分类
最新评论

groovy一些知识点

    博客分类:
  • java
阅读更多
一、代码块
在代码块中用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_demo

    这个项目是:属于入门级别的案例,通过该案例可以很快掌握groovy相关的知识点

    java开源包7

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java班级管理源码-CIYOU:翻转课堂模式的小学网络教学平台,基于Groovy,使用SpringBoot+Mybatis框架、Shiro安

    java班级管理源码 CIYOU 思源教育 该项目是基于翻转课堂实现的小学网络教育平台。 国内已经有很多尝试使用翻转课堂模式的教学网络平台,但是现在大多数的网络...相反会继续后面的教学任务,但是知识点与知识点之间是有

    Grails权威指南

     2.1 groovy和java的异同  2.1.1 相同点  2.1.2 不同点  2.2 基础知识  2.1.1 类声明 . 2.2.2 语言级断言(assertion)  2.2.3 groovy字符串  2.2.4 闭包(closures)  2.2.5 列表...

    GRAILS课程学习记录总结

    Grails 是一个注重成效的开源 Web...要理解这些内容,你得需要点面向对象编程和 MVC Web 应用开发的基础知识。虽然阅读 并不要求熟悉 Java,但如果熟悉的话,你肯定能从中受益。 你还会看到这些例子大量用到了 Groovy。

    java前后端分离源码-yalla-challenge:yalla-挑战

    理解代码分离的关注点 网址结构 要求 吉特 Java 1.8 Grails 4.0.0 让项目运行起来,可以从grails网站获取帮助 IntelliJ 社区版(可选,但推荐) 任务概述 我们需要一个新页面,其中包含一个供用户输入 github 帐户...

    JavaBase:Java基础学习

    Java基础学习 基础 进阶 ...使用了Gradle作为构建工具,将知识点分成了多个子项目,然后将所有的依赖项放在了dependency.gradle中其他的子项目引用定义的依赖,实现了依赖的统一管理 同类仓库 baeldung

    JAVA上百实例源码以及开源项目

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    JAVA上百实例源码以及开源项目源代码

    EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...

    java开源包1

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包11

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包2

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包3

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包6

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包5

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包10

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包4

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包8

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包9

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

Global site tag (gtag.js) - Google Analytics