返回介绍

3. 脚本基类

发布于 2025-01-04 00:44:53 字数 3262 浏览 0 评论 0 收藏 0

3.1 Script 类

Groovy 脚本经常被编译为类。比如下面这个简单的脚本:

println 'Hello from Groovy'

会被编译扩展自 groovy.lang.Script 抽象类的类。该类只包含一个抽象方法: run 。当脚本编译时,语句体就会成为 run 方法,脚本中的其他方法都位于实现类中。 Script 类为通过 Binding 集成应用程序提供了基本支持。如下例所示:

def binding = new Binding()             1⃣️     
def shell = new GroovyShell(binding)        2⃣️   
binding.setVariable('x',1)            3⃣️   
binding.setVariable('y',3)
shell.evaluate 'z=2*x+y'              4⃣️   
assert binding.getVariable('z') == 5        5⃣️   

1⃣️ 被用于在脚本和调用类间共享数据的绑定对象。
2⃣️ 与该绑定对象联合使用的 GroovyShell
3⃣️ 输入变量从位于绑定对象内部的调用类进行设置。
4⃣️ 然后计算脚本。
5⃣️ z 变量导出到绑定对象中。

在调用者和脚本间共享数据是一种很使用的方式,但在有些情况下却未必有较高的效率或实用性。为了应付那种情况,Groovy 允许我们设置自己的基本脚本类。脚本基类必须扩展自 groovy.lang.Script ,属于一个单独的抽象方法类别。

abstract class MyBaseClass extends Script {
  String name
  public void greet() { println "Hello, $name!" }
}

自定义脚本基类可以在编译器配置中声明,如下所示:

def config = new CompilerConfiguration()               1⃣️               
config.scriptBaseClass = 'MyBaseClass'                 2⃣️ 
def shell = new GroovyShell(this.class.classLoader, config)      3⃣️   
shell.evaluate """
  setName 'Judith'                         4⃣️   
  greet()
"""

1⃣️ 创建一个自定义的编译器配置。
2⃣️ 将脚本基类设为我们自定义的脚本基类。
3⃣️ 然后创建一个使用该配置的 GroovyShell 。 4⃣️ 脚本然后扩展该脚本基类,提供对 name 属性及 greet 方法的直接访问。

3.2 @BaseScript 注释

在脚本中直接使用 @BaseScript 注释也是个不错的办法:

import groovy.transform.BaseScript

@BaseScript MyBaseClass baseScript
setName 'Judith'
greet()

上例中,通过 @BaseScript 的注释,变量类型指定为脚本基类。另一种方法是设置基类是 @BaseScript 注释的成员:

@BaseScript(MyBaseClass)
import groovy.transform.BaseScript

setName 'Judith'
greet()

3.3 替代的抽象方法

由前面的几个例子看到,脚本基类属于一种单独的抽象方法类型,需要实现 run 方法。 run 方法由脚本引擎自动执行。在有些情况下,可能会由基类实现 run 方法,而提供了另外一种抽象方法用于脚本体,这是比较有意思的一种做法。例如,脚本基类的 run 方法会在执行 run 方法之前执行一些初始化,如下所示:

abstract class MyBaseClass extends Script {
  int count
  abstract void scriptBody()           1⃣️            
  def run() {                  
    count++                  2⃣️       
    scriptBody()               3⃣️       
    count                  4⃣️       
  }
}

1⃣️ 脚本基类定义了一个(只有一个)抽象方法。 2⃣️ run 方法可以被重写,并在执行脚本体之前执行某个任务。
3⃣️ run 调用抽象的 scriptBody 方法,后者委托给用户脚本。 4⃣️ 然后它能返回除了脚本值之外的其他内容。

如果执行下列代码:

def result = shell.evaluate """
  println 'Ok'
"""
assert result == 1

你就会看到脚本被执行,但计算结果是由基类的 run 方法所返回的 1 。如果使用 parse 代替 evaluate ,你就会更清楚,因为你会在同一脚本实例上执行多次 run 方法。

def script = shell.parse("println 'Ok'")
assert script.run() == 1
assert script.run() == 2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文