AviatorScript轻量级高性能脚本语言
简介
在 5.0
版本以前,它的名字是叫 Aviator ,定位一直只是一个表达式引擎,不支持 if/else 条件语句(仅有三元运算符支持 ?:
),没有内置的 for/while 循环支持(虽然你可以用 seq 库类似函数式的方式来处理集合),也没有赋值(后来在 4.0 引入),没有作用域的概念(也在 4.0 引入 lambda 函数后部分实现)等等一般语言常见的能力。在 5.0
版本后,它变成了一门脚本语言,叫:AviatorScript 。
在 5.0
,新加了如下新特性:
大括号 { ... }
括起来的词法作用域。let
语句用于定义局部变量。条件语句
if/elsif/else
。循环语句
for
和while
,以及相应的break
和continue
语句支持。return
语句用于从脚本或者函数中返回值。fn hello() { println("hello"); }
新的 fn 语法用于定义命名函数。## 单行注释
注释支持模块系统
new
语法用于创建对象
使用
AviatorScript 可以单纯的作为脚本语言使用,也可以和 Java 配合使用。
单纯的作为脚本语言使用
作为脚本语言使用时,需要下载一个 aviator
,然后用它去执行脚本文件。
下载:
执行下面命令下载,如果你电脑没有安装 wget
工具,你也可以直接打开 https://raw.githubusercontent.com/killme2008/aviator/master/bin/aviator,然后把里面的内容复制下来保存成一个可执行文件。然后把它放在环境变量中,可以全局访问到它
$ wget https://raw.githubusercontent.com/killme2008/aviator/master/bin/aviator
$ chmod u+x aviator
初始化:
下载完后,需要执行一下命令,它会自动在 ~/.aviatorscrip
下载所需要的依赖。
╰─$ aviator
Downloading AviatorScript now...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 148 100 148 0 0 249 0 --:--:-- --:--:-- --:--:-- 248
100 159 100 159 0 0 158 0 0:00:01 0:00:01 --:--:-- 158
100 583k 100 583k 0 0 51321 0 0:00:11 0:00:11 --:--:-- 35877
Usage: java com.googlecode.aviator.Main [file] [args]
: java com.googlecode.aviator.Main -e [script]
: java com.googlecode.aviator.Main -v
执行脚本文件:
下载好相关的环境后,就可以编写一个脚本文件了,文件名一般以 .av
结尾,这个不是必须的,你想以其他结尾也可以
test.av:
println("Hello World!");
然后执行该脚本文件:
╰─$ aviator test.av
Hello World!
null
界面输出 Hello World!
,最后一行的 null
表示是整个表达式的执行结果,就是返回值的意思,比如定义 return
时,这个 null 就会变成 return 的值,我们做如下更改:
test.av:
println("Hello World!");
return "success";
我们添加了一个 return
数据,然后执行这个脚本文件:
╰─$ aviator test.av
Hello World!
success
执行结果就会变成我们定义的 return 数据。
具体的可参考文档 aviator 命令行
配合 Java 使用
配合 Java 使用时,需要导入 Aviator 的依赖,可以在 [search.maven.org](https://search.maven.org/search?q=g:com.googlecode.aviator AND a:aviator&core=gav) 查看可用的版本。
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>{version}</version>
</dependency>
导入依赖后,我们先来演示执行一个 1+1
操作:
int result = (int) AviatorEvaluator.execute("return 1+1;");
System.out.println(result);
上面代码中,我们直接返回 1+1
的结果,然后输出,但是当我们执行的时候,就回报如下错误:
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
at top.mjava.demo.AviatorDemo.demo5(AviatorDemo.java:19)
at top.mjava.demo.AviatorDemo.main(AviatorDemo.java:15)
这是因为在 Aviator 中任何整数都将被转换为 Long 类型,而 Long 类型是不能转换为 Integer 类型的,所以会报上面的错误。所以我们要将 int 改为 long 即可:
long result = (long) AviatorEvaluator.execute("return 1+1;");
System.out.println(result);
输出:
2
挂载 Java 方法
在 Aviator 中,除了可以使用它提供的法来创建函数外,还可以挂载 Java 的自定义方法,然后在 Aviator 脚本中使用。
定义自定义的 Java 方法时,需要继承 AbstractFunction
抽象类,然后重写 call
和 getName
这两个方法:
- call : 方法具体逻辑代码
- getName : 在 Aviator 中使用时的函数名
定义自定义函数:
这边自定义了一个加法运算的方法,传入两个参数然后计算它们的和
class AddFunction extends AbstractFunction{
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
long p1 = (long) arg1.getValue(env);
long p2 = (long) arg2.getValue(env);
long result = p1+p2;
return AviatorLong.valueOf(result);
}
@Override
public String getName() {
return "add";
}
}
使用自定义函数:
如果要在 Aviator 脚本中使用这个自定义的函数时,需要先注册这个 Java 类,然后在 Aviator 脚本中使用 getName()
返回的方法名作为函数名来调用:
// 注册自定义函数
AviatorEvaluator.addFunction(new AddFunction());
// 使用自定义函数
long result = (long) AviatorEvaluator.execute("return add(2,1);");
System.out.println(result);
输出:
3