Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Groovy中利用闭包抽象化相似方法中的条件逻辑_创想鸟

Groovy中利用闭包抽象化相似方法中的条件逻辑

Groovy中利用闭包抽象化相似方法中的条件逻辑

本文探讨了如何通过groovy的闭包特性,优雅地合并那些仅在条件判断逻辑上有所差异的相似方法。通过设计一个通用的等待机制,该机制接受一个返回布尔值的闭包作为条件检查器,我们能够实现代码的高度复用和灵活性。文章详细介绍了如何构建这样的通用方法,并进一步优化了闭包参数传递,以提升性能和代码可读性,最终达到减少冗余、提高维护性的目标。

在软件开发中,我们经常会遇到这样的场景:有多个方法在执行流程上大体相同,但它们的核心差异仅在于判断某个操作是否成功的条件逻辑。如果为每个不同的条件都编写一个独立的方法,会导致大量的代码重复,降低代码的可维护性和可读性。Groovy语言凭借其强大的闭包特性,为解决这类问题提供了一种优雅且高效的方案。

相似方法的挑战

考虑以下两个Groovy方法示例:

def someCondition = falsedef method1() {    while(!someCondition) {        def connectionStatus = getConnectionStatus() // 返回 200, 404 等        if (connectionStatus == 200) {            someCondition = true        } else {            println "重复直到连接状态为 200"            sleep 15        }    }}def method2(){    while(!someCondition) {        def result = getResult() // A, B, C 等        if (result in ["A", "B", "C"]) {            someCondition = true        } else {            println "等待直到结果为 A, B 或 C"            sleep 15            result = getResult() // 再次调用检查结果是否改变        }    }}

这两个方法都包含一个循环,不断检查某个条件,直到条件满足为止,期间会进行短暂停顿。它们的主要区别在于 if 语句内部的判断逻辑:method1 检查连接状态是否为200,而 method2 检查结果是否在特定列表中。这种结构上的相似性表明存在抽象和合并的可能性。

利用闭包实现通用等待机制

Groovy的闭包允许我们将一段代码逻辑作为参数传递给方法。这正是解决上述问题的关键。我们可以设计一个通用的 waitUntil 方法,它接受一个闭包,该闭包负责执行实际的条件检查并返回一个布尔值,指示条件是否满足。

基础 waitUntil 方法

以下是 waitUntil 方法的基本实现,它包含重试机制和休眠时间:

/** * 异步等待直到指定条件满足。 * * @param sleep 单次重试失败后的休眠时间(毫秒),默认为1毫秒。 * @param maxRetries 最大重试次数,默认为10次。 * @param test 一个返回布尔值的闭包,用于测试条件是否满足。 *             当闭包返回 true 时,表示条件已满足,等待结束。 */def waitUntil(int sleep = 1, int maxRetries = 10, Closure test) {    int retries = 0    while (retries++ < maxRetries && !test()) {        println "第 ${retries}/${maxRetries} 次尝试失败,休眠 ${sleep} 毫秒后重试"        Thread.sleep(sleep)    }    // 如果循环结束时条件仍未满足,可以考虑抛出异常或返回 false    // 但在这个例子中,我们假设达到最大重试次数后循环自然结束。}

这个 waitUntil 方法有三个参数:

sleep: 每次重试失败后的休眠时间(毫秒)。maxRetries: 最大重试次数。test: 一个 Closure 类型的闭包,它不接受参数,并且预期返回一个布尔值。当此闭包返回 true 时,表示等待条件已满足。

使用示例

现在,我们可以使用这个通用的 waitUntil 方法来替换之前的两个独立方法:

// 假设 getResult() 和 getConnectionStatus() 是已定义的方法// def getResult() { /* ... */ }// def getConnectionStatus() { /* ... */ }// 替换 method2 的逻辑waitUntil {    getResult() in ["A", "B", "C"]}// 替换 method1 的逻辑 (假设 getConnectionStatus() 存在)waitUntil {    getConnectionStatus() == 200}

我们还可以灵活地调整重试参数:

Word-As-Image for Semantic Typography Word-As-Image for Semantic Typography

文字变形艺术字、文字变形象形字

Word-As-Image for Semantic Typography 62 查看详情 Word-As-Image for Semantic Typography

// 休眠 100 毫秒,默认重试次数waitUntil(100) {    getResult() in ["A", "B", "C"]}// 休眠 100 毫秒,最多重试 5 次waitUntil(100, 5) {    getResult() in ["A", "B", "C"]}

通过这种方式,我们成功地将重复的等待和重试逻辑抽象出来,只留下不同的条件判断部分作为闭包传入,极大地提高了代码的复用性。

性能优化:避免重复创建对象

在上述示例中,getResult() in [“A”, “B”, “C”] 这样的表达式会在每次闭包调用时创建一个新的 [“A”, “B”, “C”] 列表。对于快速循环或长时间运行的任务,这可能会导致频繁的对象创建和垃圾回收负担。为了优化这一点,我们可以将这些“期望值”作为参数传递给 waitUntil 方法,然后由 waitUntil 方法再将它们传递给闭包。

优化后的 waitUntil 方法

/** * 异步等待直到指定条件满足,并支持向闭包传递期望值。 * * @param expectedResult 传递给闭包的期望结果值,可以是任意类型。 * @param sleep 单次重试失败后的休眠时间(毫秒),默认为1毫秒。 * @param maxRetries 最大重试次数,默认为10次。 * @param test 一个接受一个参数并返回布尔值的闭包,用于测试条件是否满足。 *             闭包的参数将是 `expectedResult`。 */def waitUntil(Object expectedResult, int sleep = 1, int maxRetries = 10, Closure test) {    int retries = 0    while (retries++ < maxRetries && !test(expectedResult)) { // 将 expectedResult 传递给闭包        println "第 ${retries}/${maxRetries} 次尝试失败,休眠 ${sleep} 毫秒后重试"        Thread.sleep(sleep)    }}

在这个优化版本中,waitUntil 方法多了一个 expectedResult 参数,并且它会将这个参数传递给 test 闭包。在Groovy中,如果闭包只接受一个参数,可以使用隐式参数 it 来引用它。

优化后的使用示例

// 替换 method2 的逻辑,并优化性能waitUntil(["A", "B", "C"]) { expected -> // 闭包接受一个参数,这里命名为 expected    getResult() in expected}// 或者使用隐式参数 'it'waitUntil(["A", "B", "C"]) {    getResult() in it // it 指代传入的 ["A", "B", "C"]}// 替换 method1 的逻辑// 对于简单值,可以直接传递,闭包中直接比较waitUntil(200) { expectedStatus ->    getConnectionStatus() == expectedStatus}

通过这种方式,[“A”, “B”, “C”] 列表只会在 waitUntil 方法调用时创建一次,而不是在每次闭包执行时都创建,从而减少了垃圾回收的压力。

总结与注意事项

通过Groovy的闭包,我们可以非常灵活地抽象和重用那些仅在条件逻辑上有所差异的方法。这种模式不仅减少了代码重复,提高了可维护性,也使得代码意图更加清晰。

关键点:

高阶函数思维: 将条件判断逻辑封装成一个可传递的单元(闭包)。代码复用: 核心的循环、重试、休眠逻辑被集中管理。灵活性: 可以轻松地为不同的场景定制条件、休眠时间和重试次数。性能优化: 通过将期望值作为参数传递给主方法,再由主方法传递给闭包,避免了闭包内部重复创建对象。

在实际应用中,你可能还需要考虑更完善的错误处理,例如在达到最大重试次数后抛出特定异常,或者提供一个回调函数来处理每次重试失败时的日志记录或额外操作。这种基于闭包的模式是Groovy在编写简洁、可维护且功能强大的代码方面的强大体现。

以上就是Groovy中利用闭包抽象化相似方法中的条件逻辑的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/989574.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
css引入外部CSS与JS依赖关系处理
上一篇 2025年12月1日 21:24:56
消息称某厂大屏双折机型明年 Q1 亮相:骁龙 8 Gen4 处理器,预计为 OPPO Find N5
下一篇 2025年12月1日 21:25:04

相关推荐

  • Debian系统如何配置Golang日志级别

    Debian系统如何配置Golang日志级别Debian系统如何配置Golang日志级别Debian系统如何配置Golang日志级别Debian系统如何配置Golang日志级别

    在debian系统上配置golang应用的日志级别,需要遵循以下步骤: 选择日志库: 首先,选择合适的日志库。Go标准库的log包功能简单,而第三方库如logrus和zap则提供更强大的功能和性能。 设置日志级别: 根据所选日志库,设置相应的日志级别。不同库的设置方法有所不同。 使用标准库log G…

    2026年9月25日 • 用户投稿
    100
  • Rokid 开启海外众筹 或破 AI 眼镜最高筹款记录 9 月开售

    Rokid 开启海外众筹 或破 AI 眼镜最高筹款记录 9 月开售Rokid 开启海外众筹 或破 AI 眼镜最高筹款记录 9 月开售Rokid 开启海外众筹 或破 AI 眼镜最高筹款记录 9 月开售Rokid 开启海外众筹 或破 AI 眼镜最高筹款记录 9 月开售

    据 cnmo 消息,rokid 即将在美国纽约曼哈顿举行 rokid glasses 的海外发布会,当天还将同步启动该产品在 kickstarter 平台的国际众筹项目。目前,rokid 已通过海外社交媒体等渠道展开预热宣传,相关产品信息也已上线 kickstarter 官网。行业预测认为,本次 r…

    2026年9月25日 • 用户投稿
    900
  • VSCode 怎样设置编辑器的字体连写效果 VSCode 字体连写效果的创意设置教程​

    要让vscode支持字体连写,需先安装支持连写的字体如fira code,再在settings.json中配置”editor.fontfamily”并将”editor.fontligatures”设为true,最后重启vscode验证效果;若不生效,检…

    2026年9月25日
    1200
  • 使用 Jackson 进行复杂类的自定义反序列化

    使用 Jackson 进行复杂类的自定义反序列化使用 Jackson 进行复杂类的自定义反序列化使用 Jackson 进行复杂类的自定义反序列化使用 Jackson 进行复杂类的自定义反序列化

    本文介绍了如何使用 Jackson 库对包含复杂嵌套类的 JSON 字符串进行自定义反序列化。通过 ObjectMapper 的 readValue 方法可以实现简单场景下的自动反序列化。针对需要定制化处理的场景,可以结合 ObjectMapper 和自定义反序列化器来实现更灵活的反序列化逻辑,并提…

    2026年9月25日 • 用户投稿
    900
  • 天猫行业标准有哪些?如何分析行业数据?详解天猫四大行业标准体系!

    天猫行业标准有哪些?如何分析行业数据?详解天猫四大行业标准体系!天猫行业标准有哪些?如何分析行业数据?详解天猫四大行业标准体系!天猫行业标准有哪些?如何分析行业数据?详解天猫四大行业标准体系!天猫行业标准有哪些?如何分析行业数据?详解天猫四大行业标准体系!

    在天猫这个日活破亿的电商主战场中,行业规范是入场门槛,数据运营则是突围关键。目前天猫已构建起覆盖商品品质、服务响应、营销合规与物流履约的四大标准框架,并依托直通车、生意参谋等工具打造了全链路的数据分析体系。本文将深入解读天猫核心规则,并结合真实案例展示如何借助多维数据提升店铺竞争力。 一、天猫四大核…

    2026年9月25日 • 用户投稿
    700
  • 如何通过Golang日志诊断Debian网络问题

    如何通过Golang日志诊断Debian网络问题如何通过Golang日志诊断Debian网络问题如何通过Golang日志诊断Debian网络问题如何通过Golang日志诊断Debian网络问题

    本文介绍如何利用Golang日志机制在Debian系统中高效诊断网络问题。我们将探讨几种实用方法,帮助您快速定位并解决网络连接故障。 一、日志记录 标准库log包: Golang的log包是记录网络请求和响应细节的理想选择。 在发送请求前后添加日志,可以清晰地追踪请求的发送和接收过程。以下是一个简单…

    2026年9月25日 • 用户投稿
    000
  • MySQL中文标题大小写区分问题探讨

    MySQL中文标题大小写区分问题探讨MySQL中文标题大小写区分问题探讨MySQL中文标题大小写区分问题探讨MySQL中文标题大小写区分问题探讨

    MySQL中文标题大小写区分问题探讨 MySQL是一个常用的开源关系型数据库管理系统,具有良好的性能和稳定性,在开发中被广泛应用。在使用MySQL过程中,我们经常会遇到大小写区分的问题,尤其是涉及到中文标题的情况下。本文将探讨MySQL中文标题大小写区分的问题,并提供具体的代码示例帮助读者理解和解决…

    2026年9月25日 • 用户投稿
    000
  • 松下携全场景智慧生活方案亮相第四届数贸会旗舰洗护新品首秀

    松下携全场景智慧生活方案亮相第四届数贸会旗舰洗护新品首秀松下携全场景智慧生活方案亮相第四届数贸会旗舰洗护新品首秀松下携全场景智慧生活方案亮相第四届数贸会旗舰洗护新品首秀松下携全场景智慧生活方案亮相第四届数贸会旗舰洗护新品首秀

    第四届全球数字贸易博览会(以下简称“数贸会”)于2025年9月25日在杭州大会展中心隆重启幕。松下电器以“百年匠心 智慧怡居”为主题,携全系列住空间家电产品及创新互动体验登陆8号馆智慧空间展区,通过场景化展陈展示数字技术驱动下的高品质生活解决方案,并联动松下商城打造多元互动模式,推动数字贸易与消费体…

    2026年9月25日 • 用户投稿
    200
  • 豆包AI如何调用外部API 实现AI与第三方服务联动的方法

    本文旨在探讨豆包AI如何通过调用外部API,从而实现与第三方服务的智能联动。我们将详细介绍实现这一功能的核心原理以及具体的操作步骤。通过理解API调用的机制并在豆包AI中进行相应的配置,用户可以赋予豆包AI连接互联网世界、获取实时信息、执行特定任务的能力,极大地扩展了AI的应用场景和智能化水平。文章…

    2026年9月25日
    000
  • 这台五万元的相机,哈苏想卖给「普通人」

    这台五万元的相机,哈苏想卖给「普通人」这台五万元的相机,哈苏想卖给「普通人」这台五万元的相机,哈苏想卖给「普通人」这台五万元的相机,哈苏想卖给「普通人」

    拍照,可能是这个时代门槛最低的创作行为了。 我们每天都在生产和消费着海量的图片,记录变得前所未有地容易,但容易,就等于好吗? 过去,哈苏的答案是倾向于「好」,但代价是「难」——你需要理解光圈、快门,要背着沉重的三脚架,甚至要在特定的拍摄环境中,才能驾驭这份极致的画质。 在推出了备受瞩目的 X2D 1…

    2026年9月25日 • 用户投稿
    200
  • 豆包是否可以本地部署 自主可控环境下运行豆包的技术路径说明

    本文旨在解答关于豆包是否可以在本地环境下进行部署并实现自主可控运行的问题。目前,豆包主要以云服务形式提供,用户通过网络访问其功能。要在自主可控的环境下运行类似的大型语言模型能力,通常需要采用不同的技术路径,即在本地计算资源上部署可用的AI模型。本文将概述实现本地自主可控AI运行的通用技术路线和关键步…

    2026年9月25日
    300
  • 荣耀 300 系列系统升级,后续多款新机待发

    荣耀 300 系列系统升级,后续多款新机待发荣耀 300 系列系统升级,后续多款新机待发荣耀 300 系列系统升级,后续多款新机待发荣耀 300 系列系统升级,后续多款新机待发

    日前,荣耀 300 系列手机迎来 magicos 9.0.0.187 版本升级,此次更新带来了清理建议、ai 通话等多项新功能,系统升级将以分批推送的形式逐步覆盖用户。 本次更新的主要亮点如下: 图库方面新增“清理建议”功能,可智能识别重复照片、相似图片及超大视频,帮助用户更高效地管理存储空间; 通…

    2026年9月25日 • 用户投稿
    500
  • PHP文件引入时参数传递机制详解与最佳实践

    在php中,直接通过url查询字符串方式向`require`或`include`引入的文件传递参数是无效的,这会导致“未定义变量”错误。本文将深入探讨php文件引入的原理,并提供三种正确的参数传递方法:利用作用域共享、手动填充`$_get`数组,以及推荐的通过函数或类进行封装,旨在帮助开发者构建更健…

    2026年9月25日
    000
  • sublime怎么设置字体和字号 _sublime字体与字号调整方法

    sublime怎么设置字体和字号 _sublime字体与字号调整方法sublime怎么设置字体和字号 _sublime字体与字号调整方法sublime怎么设置字体和字号 _sublime字体与字号调整方法sublime怎么设置字体和字号 _sublime字体与字号调整方法

    先修改用户设置文件以调整字体和字号,打开Preferences → Settings,在右侧User配置中添加”font_face”和”font_size”选项,如{“font_face”: “Fira Code&#…

    2026年9月25日 • 用户投稿
    000
  • Java 8 使用 Stream API 扁平化嵌套 Map 并提取首个元素

    Java 8 使用 Stream API 扁平化嵌套 Map 并提取首个元素Java 8 使用 Stream API 扁平化嵌套 Map 并提取首个元素Java 8 使用 Stream API 扁平化嵌套 Map 并提取首个元素Java 8 使用 Stream API 扁平化嵌套 Map 并提取首个元素

    本文将详细介绍如何使用 Java 8 的 Stream API 将一个嵌套的 Map 结构进行扁平化处理,并从中提取所需的数据。 具体来说,我们将把 Map<Integer, Map<String, List>> 转换为 Map,其中新 Map 的键是原内部 Map 的键,值…

    2026年9月25日 • 用户投稿
    1200
  • 首个对话式音乐创作 Agent“Tunee”正式公测

    首个对话式音乐创作 Agent“Tunee”正式公测首个对话式音乐创作 Agent“Tunee”正式公测首个对话式音乐创作 Agent“Tunee”正式公测首个对话式音乐创作 Agent“Tunee”正式公测

    趣丸科技旗下天谱乐团队自主研发的国内首款对话式音乐创作agent“tunee”近日正式启动全球公测,全面向公众开放使用。 据悉,用户只需通过自然语言描述自己的音乐设想,即便表达模糊,Tunee也能自动完成需求解析、方案设计到实际作曲的完整流程,最终输出契合用户意图的原创音乐作品。 Tunee采用先进…

    2026年9月25日 • 用户投稿
    500
  • Debian syslog如何定制报警机制

    Debian syslog如何定制报警机制Debian syslog如何定制报警机制Debian syslog如何定制报警机制Debian syslog如何定制报警机制

    本文介绍如何在Debian系统中定制syslog报警机制,利用rsyslog实现更灵活的日志监控和告警。 首先,确保已安装rsyslog: sudo apt-get updatesudo apt-get install rsyslog 接下来,修改rsyslog配置文件,/etc/rsyslog.c…

    2026年9月25日 • 用户投稿
    100
  • 对话逐际动力张巍:造机器人很容易,关键是用起来

    对话逐际动力张巍:造机器人很容易,关键是用起来对话逐际动力张巍:造机器人很容易,关键是用起来对话逐际动力张巍:造机器人很容易,关键是用起来对话逐际动力张巍:造机器人很容易,关键是用起来

    “让天下没有难落地的机器人。” 在这样向量子位表达定位和使命后,逐际动力”解释了”为何会成为阿里投资的第一家具身智能机器人公司。 在这样解释定位和使命后,量子位大概感受到了逐际动力被投资的原因—— 至少是成为阿里第一个具身智能投资项目的原因。 实际上,…

    2026年9月25日 • 用户投稿
    500
  • 修改 Android KeyStore 中 KeyPair 的用途

    修改 Android KeyStore 中 KeyPair 的用途修改 Android KeyStore 中 KeyPair 的用途修改 Android KeyStore 中 KeyPair 的用途修改 Android KeyStore 中 KeyPair 的用途

    本文档介绍了如何在 Android KeyStore 中修改现有 KeyPair 的用途,使其支持密钥协商 (Key Agreement) 操作。通过示例代码展示了如何利用 KeyStore.setEntry 方法在 Android 13 (API 33) 及以上版本中导入 KeyPair 并设置所…

    2026年9月25日 • 用户投稿
    600
  • 专业横评便携微单:佳能R50V凭6K超采样+精准快速追焦 成 8000 元内全能首选

    专业横评便携微单:佳能R50V凭6K超采样+精准快速追焦  成 8000 元内全能首选专业横评便携微单:佳能R50V凭6K超采样+精准快速追焦  成 8000 元内全能首选专业横评便携微单:佳能R50V凭6K超采样+精准快速追焦  成 8000 元内全能首选专业横评便携微单:佳能R50V凭6K超采样+精准快速追焦  成 8000 元内全能首选

    随着旅行摄影与短视频创作的需求激增,便携微单已成为多数用户的核心影像工具。面对 8000元以下微单市场的繁杂选择,专业影像评测团队通过150小时实测(涵盖画质解析力、防抖稳定性、低光对焦等 15 项核心指标),结合近万份用户口碑反馈,筛选出 3 款高潜力机型。其中佳能 R50V 凭借“画质无短板、便…

    2026年9月25日 • 用户投稿
    200

发表回复

登录后才能评论
关注微信