Groovy进阶之函数、闭包和类

2,191 阅读7分钟
原文链接: www.sunnyang.com

上一篇文章Groovy入门之语法和变量定义重点记录的是Groovy的语法以及变量,这一篇文章继续学习Groovy的一些相关知识点。本文的重点是函数和闭包、类和对象,知识点涉及到与Java一样的地方在文章中就不做介绍了,重点将一些与Java不同的地方。另外如果有人接触过JavaScript,相信多数也了解JavaScript中闭包这个概念,但是Groovy中闭包与JavaScript闭包是两个完全不同概念。

函数与闭包

函数

有些人可能对函数和方法的叫法一直不太清楚。事实上没有本质区别,在面向过程的语言中一般称为函数,在函数式编程中一般都叫做函数。方法的一般是类的方法,在某一个类中定义的称之为方法。

1.在Groovy中除非指定了确定的返回类型,void也可以作为返回值的一种,否则定义函数必须加上关键字def。

2.在定义函数需要传参时可以不设置设置参数的类型,默认是Object类型的,如果用def关键字设置参数类型,事实上也是使用的Object定义参数的。

function_params

3.在调用函数时,如果所定义的函数有参数,在使用的时候可以不使用括号,但是必须得传入参数,参数与函数名以空格隔开。

如果不出入参数必须添加括号,否则代码编译可以通过,但是运行时会出错,会将函数误认为是一个属性。

如果所定义的函数没有参数,在调用的时候必须添加括号,否则运行出错,会将函数误认为是一个属性。

函数调用的时候参数的个数必须匹配,否则也会报错,提示没有定义该函数,如果单个参数除外,可以不用输入参数,系统默认赋值null。

4.函数可以有返回值,如果有显示地使用return关键字,则返回return指定的返回值,其后面的语句不再执行。

如果没有显式地使用return关键字,则返回函数最后一行语句的运行结果。

如果使用void关键字代替def关键字定义函数,则函数的返回值将为null。

5.支持函数重载,当参数个数不同时,函数名称可以同名。

6.函数内不可以访问函数外的变量

7.Groovy支持不定长参数。

8.函数可以赋值给其它函数,使用语法标记&将函数赋予新的函数。

闭包

在Javascript中闭包的定义:有权访问另外一个函数作用域中的变量的函数。

Groovy中闭包是这么定义的:可以用作函数参数和方法参数的代码块。可以把这个代码块理解为一个函数指针。

闭包的定义格式:

在这里可以看出来这里的闭包跟JavaScript中以字面量形式定义对象格式类似。

从这里也可以看出来Groovy中闭包表示形式和闭包跟JavaScript中所讲解的闭包是完全不同的。

1.闭包可以访问外部的变量,记住一点方法是不能访问外部变量的。

2.闭包调用的方式有两种,闭包.call(参数)或者闭包(参数),在调用的时候可以省略圆括号。

3.闭包是有返回值的,默认最后一行语句就是该闭包的返回值,如果最后一行语句没有不输入任何类型,闭包将返回null。

4.闭包可以有参数,如果没有定义参数,会有一个隐式的默认参数it,如果没有参数可以将[参数]和[->]省略。

如果存在参数,在[->]之前的就是参数,如果只有一个参数,参数可以省略。

闭包中参数名称不能与闭包内或闭包外的参数名重名

5.闭包可以作为一个参数传递给另一个闭包,也可以在闭包中返回一个闭包。

6.闭包的一些快捷写法,当闭包作为闭包或方法的最后一个参数,可以将闭包从参数圆括号中提取出来接在最后。

如果闭包中不包含闭包,则闭包或方法参数所在的圆括号也可以省略。

对于有多个闭包参数的,只要是在参数声明最后的,均可以按上述方式省略。

7.闭包接受参数的规则,会将参数列表中所有有键值关系的参数,作为一个map组装,传入闭包作为调用闭包的第一个参数。

8.如果闭包的参数声明中没有list,那么传入参数可以设置为list,里面的参数将分别传入闭包参数。

类和对象

Groovy类与Java类似,在字节码级都被编译成Java类,由于其在定义变量上面的灵活性,所以在新建一个Groovy类时还是有一些不同的,增加了许多灵活性。由于Groovy是松散型语言,它并不强制你给属性、方法参数和返回值定义类型。如果没有指定类型,在字节码级别会被编译成Object。在定义类的属性时不用刻意加上权限修饰符,默认就是public的。

如果我们将Book类看做是一个JavaBean,事实上Groovy在编译完成后会自动帮助我们生成getter与setter方法,但是私有属性除外也就是说price属性我们不能使用getter与setter方法。

在Groovy中类名和文件名并不需要严格的映射关系,我们知道在Java中主类名必须与文件同名,但是在Groovy中一个文件可以定义多个public类。
在Groovy中可以定义与任何类不相关的方法和语句,这些方法通常称为独立方法或者松方法。

上面一个文件名定义为Structure.groovy,在这个文件中包含了类的定义和独立方法声明,它编译之后会发生什么呢。首先会生成一个与文件同名的class文件。所有的松语句都集中在run方法中,并且run方法被该类的main方法调用。独立方法被编译成了类的静态方法。与Java相似,每一个独立的类都会被编译成一个单独的class文件。因此编译Structure.groovy文件最后会被编译成Hello.class、World.class和Structure.class。上面一个文件名定义为Structure.groovy,在这个文件中包含了类的定义和独立方法声明,它编译之后会发生什么呢。首先会生成一个与文件同名的class文件。所有的松语句都集中在run方法中,并且run方法被该类的main方法调用。独立方法被编译成了类的静态方法。与Java相似,每一个独立的类都会被编译成一个单独的class文件。因此编译Structure.groovy文件最后会被编译成Hello.class、World.class和Structure.class。

本文地址:www.sunnyang.com/522.html

小结

有关Groovy的学习就先到这里,有关Groovy基础语法的讲解可以参看Groovy入门之语法和变量定义这篇博文,两篇文章主要还是偏重中一些基本使用,为的是可以更好的理解应用Android Studio的Gradle工具。笔记的记录基本都是通过浏览别人博客以及《Java脚本编程:语言、框架与模式》这本书,由于个人能力所限,文章中难免有错误疏漏之处,如若发现还望及时指出以求共同进步。

参考资料

Groovy学习笔记之块、闭包与函数

深入理解Android之Gradle

Groovy基础——Closure(闭包)详解

groovy-闭包

Java脚本编程:语言、框架与模式