本篇Groovy学习笔记第37篇。开始介绍Groovy中的扩展类型检查相关知识。学会如何定义我们的类型检查器。,在前面分享的关于类型知识,更多的是依靠Groovy中的静态类型检查器实现的。,而本篇开始要介绍的就是定义我们自己的类型检查。也就叫做类型检查扩展,定义自己的类型检查器。,类型检查扩展是一种机制,它允许DSL引擎的开发人员对常规groovy类应用静态类型检查所允许的相同类型的检查,从而使这些脚本更加安全。,PS:总的来说,类型检测扩展的相关知识,可能更多的适合于采用Groovy进行插件开发的工程师使用。用于检测定义的DSL脚本是否合规等。,下面来介绍,如何编写我们的类型检查。,Groovy可以在编译时与静态类型检查器一起使用,使用@TypeChecked注解启用。在这种模式下,编译器会变得更加冗长,并抛出错误,例如拼写错误、不存在的方法等。不过,这也带来了一些限制,其中大多数限制来自Groovy本质上仍然是一种动态语言。例如,你不能在使用标记构建器的代码上使用类型检查:,在上面的例子中,html、head、body或p方法都不存在。但是,如果执行代码,它可以工作,因为Groovy使用动态分派并在运行时转换这些方法调用。在这个构建器中,我们可以使用的标记数量和属性都没有限制,这意味着类型检查器没有机会在编译时知道所有可能的方法(标记),除非我们创建一个专用于HTML的构建器。,Groovy是实现内部DSL的首选平台。灵活的语法,结合运行时和编译时元编程功能,使Groovy成为一个有趣的选择,因为它允许程序员专注于DSL,而不是工具或实现。由于Groovy DSL是Groovy代码,因此很容易获得IDE工具的支持,而不必编写专门的插件。,在很多情况下,DSL引擎是用Groovy(或Java)编写的,然后用户代码作为脚本执行,这意味着在用户逻辑之上有某种包装器。例如,包装器可能包含在GroovyShell或GroovyScriptEngine中,它们在运行脚本之前透明地执行一些任务(添加导入、应用AST转换、扩展基本脚本等等)。通常,用户编写的脚本无需测试就可以投入生产,因为DSL逻辑达到了任何用户都可以使用DSL语法编写代码的地步。最后,用户可能会忽略他们所编写的实际上是代码。这为DSL实现者增加了一些挑战,例如确保用户代码的执行,或者在这种情况下,及早报告错误。,例如,想象一个DSL:其目标是远程驾驶火星上的漫游者。向探测器发送信息大约需要15分钟。如果漫游者执行脚本失败,出现一个错误(比如一个错字),你就有两个问题:,首先,反馈只在30分钟后出现(探测器获得脚本所需时间和接收错误所需时间),其次,脚本的某些部分已经执行,您可能必须对固定脚本进行重大更改(这意味着您需要知道漫游车的当前状态……),类型检查扩展是一种机制,它允许DSL引擎的开发人员对常规groovy类应用静态类型检查所允许的相同类型的检查,从而使这些脚本更加安全。,这里的原则是尽早失败,也就是说尽快编译脚本失败,如果可能的话向用户提供反馈(包括漂亮的错误消息)。,简而言之,类型检查扩展背后的思想是让编译器知道DSL使用的所有运行时元编程技巧,这样脚本就可以获得与冗长的静态编译代码相同级别的编译时检查。我们将看到,您可以执行普通类型检查器无法执行的检查,从而为用户提供强大的编译时检查。,@TypeChecked注释支持名为extensions的属性。此参数接受一个字符串数组,对应于类型检查扩展脚本列表。这些脚本在编译时在类路径中找到。例如:,在这种情况下,foo方法将使用普通类型检查器的规则进行类型检查,这些规则由myextension中找到的规则完成groovy脚本。,PS:注意,虽然在内部类型检查器支持多种机制来实现类型检查扩展(包括普通的旧java代码),但推荐的方法是使用那些类型检查扩展脚本。,类型检查扩展背后的思想是使用DSL来扩展类型检查器功能。这个DSL允许我们使用“event-driven”API钩入编译过程,更具体地说是类型检查阶段。例如,当类型检查器进入一个方法体时,它会抛出一个beforeVisitMethod事件,扩展可以对该事件做出反应:,假设我们手头有这个漫游者DSL。用户可以这样写:,如果你有一个这样定义的类:,脚本可以在执行之前使用以下脚本进行类型检查:,使用上面的编译器配置,我们可以透明地将@typecheck应用于脚本。在这种情况下,它将在编译时失败,输出下面的错误日志:,现在,我们将稍微更新配置以包含extensions参数:,然后将以下内容添加到类路径中:,首先:创建一个robotextension.groovy文件,然后在文件中添加下面的代码:,在这里,我们告诉编译器,如果找到一个未解析的变量,并且变量的名称为robot,那么我们可以确保该变量的类型为robot。,AST:类型检查API是一个低级API,处理抽象语法树。要开发扩展,您必须很好地了解AST,即使DSL比处理纯Java或Groovy的AST代码要容易得多。,Events:类型检查器发送以下事件,扩展脚本可以对这些事件做出反应。,具体的Events示例如下表所示:
,(PS: 上面的表格看不清楚的,可以访问我的博客网站:zinyan.com/?p=486)当然,扩展脚本可能由几个块组成,可以使用多个块响应同一个事件。这使得DSL看起来更好,更容易编写。然而,仅仅对事件做出反应是远远不够的。如果我们知道可以对事件做出反应,那么还需要处理错误,这意味着有几个帮助器方法可以使事情变得更简单。
文章版权声明
1 原创文章作者:cmcc,如若转载,请注明出处: https://www.52hwl.com/17088.html
2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈
3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)
4 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别