Groovy闭包的一些操作

文章目录

        • 闭包
          • 1闭包的一些用法
          • 2 闭包在字符串中的使用
          • 3 闭包中的变量
          • 4 闭包中嵌套闭包
          • 5 闭包委托策略

闭包

​ 闭包其实就是一段用{}包起来的代码,可以通过下面例子了解一下闭包。

//这是一段闭包的代码
def a = {println("hello groovy")}
//可以通过call()调用,也可以直接在后面加()条用
a.call()//hello groovy
a()//hello groovy//->前面部分是闭包参数 —>后面部分是闭包体(代码)
//这是一个无参的闭包
def b = {-> println("hello groovy")}
b.call()//有一个入参的闭包
def c= {def str -> println("hello ${str}")}
c.call("groovy")//hello groovy//有两个入参的闭包
def d= {def str,int age -> println("hello ${str},my age is ${age}")}
d.call("groovy",18)//hello groovy,my age is 18//默认入参,闭包里面有一个默认参数it,不需要显示声明,用it接受,如果定义了其他入参,该参数失效
def e ={println("hello ${it}")}//hello groovy
e.call("groovy")//hello groovy//闭包是有返回值的,如果不写返回值,就相当于返回null
def f ={println("hello ${it}")}//hello groovy
def result = f.call("groovy")//hello groovy
println(result)//nulldef g ={return ("hello ${it}")}//hello groovy
def res = g.call("groovy")//hello groovy
println(res)//hello groovy
1闭包的一些用法

​ 第一个例子是upto的使用

//从10到20,闭包打印每个数字
10.upto(20){it-> println(it)}//计算1到100之间数的和
def result=0;
1.upto(100){it -> result+=it}
println(result)//5050

upto的源码部分内容如下:

public static void upto(Number self, Number to, @ClosureParams(FirstParam.class) Closure closure) {int self1 = self.intValue();int to1 = to.intValue();if (self1 <= to1) {for (int i = self1; i <= to1; i++) {//闭包的执行部分closure.call(i);}} elsethrow new GroovyRuntimeException("The argument (" + to +") to upto() cannot be less than the value (" + self + ") it's called on.");}

​ 第二个例子times的使用

//执行10次,从0到9
10.times {it -> println(it)}

times的源码部分内容如下:

 public static void times(Number self, @ClosureParams(value=SimpleType.class,options="int")  Closure closure) {for (int i = 0, size = self.intValue(); i < size; i++) {closure.call(i);if (closure.getDirective() == Closure.DONE) {break;}}}
2 闭包在字符串中的使用

​ 在字符串中常见的一些字符串使用方法。

//便利字符串中的每个字符并打印
def s="hello groovy 2023"
s.each {it -> println(it)}//找到第一个是数字的字符
println(s.find {it -> it.isNumber()}) // 2//找到所有是数字的字符
println(s.findAll {it -> it.isNumber()})//[2, 0, 2, 3]//判断字符串中是否有一个数字
println(s.any {it -> it.isNumber()})//true//判断字符串中是不是都是数字
println(s.every {it -> it.isNumber()})//false//将字符串所有字符都转大写
println(s.collect(it-> it.toUpperCase()))//[H, E, L, L, O,  , G, R, O, O, V, Y,  , 2, 0, 2, 3]
3 闭包中的变量

​ 闭包中含有三个内置变量:this,owner,delegate

this:代表定义该闭包的类的实例对象(实例闭包)或者类本身(静态闭包)

owner:可以和this用法一样,还可以用作,当闭包中嵌套闭包的时候,这时候owner就指向定义它的闭包对象

delegate:含义大多数情况下和owner的含义一样,除非被显示的修改

​ 在Groovy脚本中定义闭包,那么this,owner,delegate指的都是当前所在脚本的类的对象(当前脚本编译后对应的就是一个脚本类型的类),看下面例子:

package com.dream21thdef a={println("a->this:"+this)//a->this:com.dream21th.Groovy_study08@576fa0println("a->owner:"+owner)//a->owner:com.dream21th.Groovy_study08@576fa0println("a->delegate:"+delegate)//a->delegate:com.dream21th.Groovy_study08@576fa0
}a.call()

​ 如果定义内部类,那么无论是闭包中还是方法中,this,owner,delegate指代的都是所在类的对象,看下面例子:

class Student{def b={println("b->this:"+this)//b->this:com.dream21th.Student@9a0cdbprintln("b->owner:"+owner)//b->owner:com.dream21th.Student@9a0cdbprintln("b->delegate:"+delegate)//b->delegate:com.dream21th.Student@9a0cdb}def test(){def c={println("c->this:"+this)//c->this:com.dream21th.Student@9a0cdbprintln("c->owner:"+owner)//c->owner:com.dream21th.Student@9a0cdbprintln("c->delegate:"+delegate)//c->delegate:com.dream21th.Student@9a0cdb}c.call()}
}Student student=new Student()//创建一个Student对象
student.b.call()//调用对象中的b闭包
student.test()//调用对象中的test方法

​ 如果定义的内容是静态的,那么this,owner,delegate指代的都是所在,看下面例子:

class Person{def static d={println("d->this:"+this)//d->this:class com.dream21th.Personprintln("d->owner:"+owner)//d->owner:class com.dream21th.Personprintln("d->delegate:"+delegate)//d->delegate:class com.dream21th.Person}def static test(){def e={println("e->this:"+this)//e->this:class com.dream21th.Personprintln("e->owner:"+owner)//e->owner:class com.dream21th.Personprintln("e->delegate:"+delegate)//e->delegate:class com.dream21th.Person}e.call()}
}Person.d.call() //类直接调用
Person.test()
4 闭包中嵌套闭包

​ 在这种情况下this指代的依然是所在类,但是ownerdelegate指代的就是嵌套的闭包的闭包,看下面例子:

def f={def g={println("g->this:"+this)//g->this:com.dream21th.Groovy_study08@7f9738println("g->owner:"+owner)//g->owner:com.dream21th.Groovy_study08$_run_closure2@141a8ffprintln("g->delegate:"+delegate)//g->delegate:com.dream21th.Groovy_study08$_run_closure2@141a8ff}g.call()
}f.call()

​ 无论在什么情况下,this指代的都是所在类或者类的对象,但是遇到闭包嵌套闭包,ownerdelegate指代的就是嵌套闭包的闭包。

ownerdelegate不同的情况:两者的含义在大多数的情况下含义一样,除非它被显示修改。通过下面的例子看

def f={def g={println("g->this:"+this)//g->this:com.dream21th.Groovy_study08@baae5println("g->owner:"+owner)//g->owner:com.dream21th.Groovy_study08$_run_closure2@22cb6aprintln("g->delegate:"+delegate)//g->delegate:com.dream21th.Person@1d1c9f2}g.delegate=person //显示修改g.call()
}f.call()
5 闭包委托策略

​ 这种用法使用很少,可以通过下面例子:

package com.dream21th//定义一个类A
class A{String namedef a={"my name is ${name}"}String toString(){a.call()}
}//定义一个类B
class B{String name
}def a =new A(name:"zhangsan")
def b =new B(name:"lisi")//${name}取值是从delegate中取值,所以delegate默认情况下指代的是当前A的对象
println(a.toString()) //my name is zhangsan//修改a的委托对象
//单纯的修改delegate不好用,因为默认情况下delegate委托机制是owner first,所以需要修改委托策略
a.a.delegate=b
println(a.toString()) //my name is zhangsana.a.delegate=b
//修改委托策略
a.a.resolveStrategy=Closure.DELEGATE_FIRST
println(a.toString()) //my name is lisi

${name}取值默认是从delegate取值,delegate默认和owner的值一样,委托机制也是owner_first优先。所以只修改delegate的值没有用,还需要修改委托策略:delegate_first

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/583813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

零基础入门跨境电商独立站,看这篇文章就够了!

对于跨境电商卖家来说&#xff0c;多平台、多站点的布局是非常重要的战略。这样做可以规避”鸡蛋放在同一个篮子里”的风险也能够追求更高的销售额和利润。同时&#xff0c;市场的变化也带来了新的发展机会&#xff0c;因此很多出海企业都希望抓住独立站的新机遇&#xff0c;抢…

Spire.Office 8.12.2 for .NET

Spire.Office 8.12.2 发布。在此版本中&#xff0c;Spire.Doc支持Word到PCL和PostScript转换中的文本整形以及确定文档是否加密&#xff1b;Spire.Presentation支持将母版页转换为图像&#xff1b;Spire.PDFViewer支持在WinForm项目中使用Ctrl滚轮实现界面缩放效果。此外&#…

KaiwuDB 受邀亮相“ACDU 中国行”数据库技术沙龙(西安站)

12月23日&#xff0c;由中国计算机学会&#xff08;CCF&#xff09;指导&#xff0c;浪潮数据库、中国数据库联盟、墨天轮数据库社区等联合主办的“ACDU 中国行”数据库技术发展与实践沙龙&#xff08;西安站&#xff09;成功举办。KaiwuDB 高级架构师赵衎衎受邀出席沙龙并做主…

win上使用wireshark 抓包 | 安装、实战抓包、筛选规则

先随便讲两句吧 win 上抓包&#xff0c;使用wireshark 直接运行&#xff0c;通过选定网卡、配置筛选规则 相比&#xff0c;在linux 上抓包&#xff0c;直接使用命令 tcpdump 再添加筛选规则 就可以 好像wireshark的一个插件不维护&#xff0c;导致需要重新安装插件&#xff0c;…

用电脑将图片转为excel表格有几种方法?怎么操作?

将图片转为Excel表格&#xff0c;一般需要借助OCR(光学字符识别)技术。OCR技术可以将图片中的文字提取出来&#xff0c;并转换成Excel表格中的数据。以下是几种常用的方法&#xff1a; 一、.使用在线OCR工具 1、打开金鸣表格文字识别&#xff08;简称金鸣识别&#xff09;网站…

MSF(Metasploit Framework)详细教程

一. 简介 Metasploit 是一个开源的渗透测试开源软件&#xff0c;也是一个逐步发展成熟的漏洞研究与渗透测试代码开发平台&#xff0c;此外也将成为支持整个渗透测试过程的安全技术集成开发与应用环境&#xff0c;2009年10月&#xff0c;Metasploit项目被一家渗透测试技术领域的…

关于StartAI生图下载问题

最近小编常常收到一些小伙伴对StartAI生图的问题反馈&#xff0c;今天为大家同一解答吧&#xff01; Q1&#xff1a;小编小编&#xff0c;为什么我生图后下载图片在文件夹中显示空白呀&#xff1f; 小编&#xff1a;当前我们StartAI版本0.4.5在下载图片时还未添加保存类型&…

Dubbo相关面试题及答案

1、Dubbo的基本架构是怎样的&#xff1f; Dubbo是一个高性能的Java RPC&#xff08;远程过程调用&#xff09;框架&#xff0c;它的基本架构主要由以下几个核心组件构成&#xff1a; Provider&#xff08;服务提供方&#xff09;&#xff1a; Provider是指暴露服务的服务提供者…

K8S Helm 安装ingress-nginx/ingress-nginx

安装ingress-nginx/ingress-nginx 参考&#xff1a;https://www.cnblogs.com/syushin/p/15271304.html 添加helm仓库 - [rootk8s-master ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx - [rootk8s-master ~]# helm repo update 下载安装…

WebGL开发航空航天学习应用

使用 WebGL 开发航空航天学习应用可以为学生提供沉浸式的三维体验&#xff0c;帮助他们了解航空航天工程、飞行原理和宇宙空间。以下是开发航空航天学习应用的一般步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c…

如何解决企业内部FTP文件传输速度过慢和安全问题

在数据化时代里&#xff0c;企业内部的文件传输永远是刚需&#xff0c;而因为 FTP协议的简单、易用、广泛支持等优点&#xff0c;让很多企业早期都普遍使用&#xff0c;随着数量量的增多&#xff0c;和对安全的要求越来越高&#xff0c;FTP也暴露出了一些列问题&#xff0c;小编…

鲫鱼养殖场污水处理设备配置报价

诸城市鑫淼环保小编带大家了解一下鲫鱼养殖场污水处理设备配置报价 一、概述 水产加工废水来自于水产加工厂的生产流程&#xff1a;原料解冻、去脏、清洗、装盘、速冻、包装以及原料冻鱼解冻、水洗、控水、消毒、清洗等工序产生生产废水&#xff0c;生产设备洗刷、车间地面产生…

AI面板识别 - 华为OD统一考试

OD统一考试 (B卷) 分值: 100分 题解: Java / Python / C++ 题目描述 AI识别到面板上有N(1 ≤ N ≤ 100)个指示灯,灯大小一样,任意两个之间无重叠。 由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2…

geyser互通服基岩版进不去

Java版需要在服务器安全组开通TCP端口&#xff08;如果有宝塔&#xff0c;也需要开通&#xff09; geyser下载好的安装运行也需要开通端口&#xff0c;但是它是UDP的&#xff08;但是我同时也开启了TCP&#xff0c;可能不需要&#xff1f; Java 版玩家隧道 Java 版玩家使用 T…

Solana 与 DePIN 的双向奔赴,会带来 DePIN 之夏吗?

作者&#xff1a;LBank Labs 研究员 F.F 编译&#xff1a;TinTinLand 原文&#xff1a;https://medium.com/lbanklabs/new-anchor-of-solana-depin-b674d04d6980 太长不看版 在过去的一年里&#xff0c;我们观察到 Solana 和 DePIN 两者都呈现出了显著的增长。这不仅是极客科…

论文阅读——Slide-Transformer(cvpr2023)

Slide-Transformer: Hierarchical Vision Transformer with Local Self-Attention 一、分析 1、改进transformer的几个思路&#xff1a; &#xff08;1&#xff09;将全局感受野控制在较小区域&#xff0c;如&#xff1a;PVT&#xff0c;DAT&#xff0c;使用稀疏全局注意力来…

Spring中有哪些扩展点

介绍 什么是spring扩展点 Spring 框架中的扩展点是指一组接口或机制&#xff0c;允许开发者在不修改核心框架源代码的情况下&#xff0c;定制和扩展 Spring 框架的功能、行为或配置。这些扩展点提供了一种方式&#xff0c;使开发者可以通过实现特定的接口、编写特定类型的类或…

使用 sourcetree 的《遴选》功能

假设你有一个分支&#xff0c;有两个提交 A&#xff0c;和B&#xff0c;你现在想在A提交的基础上把 B提交的功能做修改&#xff0c;你可以使用 遴选功能。 在A 提交的基础上新建一个分支&#xff0c;然后在B提交上面&#xff0c;右键&#xff0c;选择 遴选&#xff0c;那么B修改…

【开题报告】基于SSM的仓库管理系统设计与实现

1.引言 随着物流行业的蓬勃发展&#xff0c;仓库管理成为了企业物流运作中的关键环节。为了提高仓库管理的效率和准确性&#xff0c;开发一个基于SSM框架的仓库管理系统是非常必要和有意义的。 传统的仓库管理方式往往依赖于手工操作和纸质记录&#xff0c;这种方式存在着许多…