3. 脚本基类
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论