当前位置: 首页>后端>正文

AviatorScript 脚本语言入门

1. AviatorScript

1.1 背景

在 5.0 版本以前叫 Aviator,定位是一个表达式引擎
在 5.0 版本改名为 AviatorScript,定位是高性能、轻量级、易于和 Java 交互的寄宿于 JVM 之上的脚本语言

AviatorScript 是一门寄生在 JVM (Hosted on the JVM)上的语言,类似 clojure/scala/kotlin 等等
GitHub 地址 https://github.com/killme2008/aviatorscript
AviatorScript 在线文档:https://www.yuque.com/boyan-avfmj/aviatorscript/cpow90

2. 基本类型与语法

2.1 语法

  • ## 单行注释
  • 条件语句 if/elsif/else
  • 循环语句 for 和 while ,以及相应的 break 和 continue 语句支持

2.2 数字

  • 大整数(BigInteger)
    • 以字母N结尾 let b = 1000N;
  • 大小数类型(BigDecimal)
    • 以 M 结尾 let a = 2M;
  • 浮点数仅支持 double 类型

2.3 字符串

  • 只要以单引号或者双引号括起来的连续字符就是一个完整的字符串对象
    • "hello world" 或者 'hello world'
  • 字符串插值(String Interpolation)
    • #{} 动态表达式
let name = "aviator";
let a = 1;
let b = 2;
let s = "hello, #{name}, #{a} + #{b} = #{a + b}";
p(s);

2.4 变量

AviatorScript 中变量的定义和赋值是不可分割的,定义一个变量的同时需要给他赋值
AviatorScript 是动态类型语言,变量的类型随着赋值而改变

a = 1;
println(type(a));

nil
nil 类似于 java 中的 null,表示当前变量还没有赋值

在 Java 中, null 只能参与等于和不等于的比较运算,而在 AviatorScript 中, nil 可以参与所有的比较运算符,只是规定任何类型都比nil大除了nil本身

a = 3;
println("a > nil: " + (a > nil));
println("0.0 > nil: " + (0.0 > nil));

3. 条件语句

3.1 if 语句

if(true) {
   println("some thing...");
}
## 注意:代码块都必须用大括号包起来,哪怕是单行语句

if 后面连着的表达式的括号可以忽略

if true {
   println("some thing...");
}

3.2 elsif 语句

let a = rand(120);

if a > 100 {
  println("a is greater than 100.");
} elsif a > 10 {
  println("a is greater than 10.");
} else {
   println("a is less than 10 ");
}

4. 循环语句

AviatorScript 支持 for 和 while 两种循环语句

4.1 for 循环


continue/break/return
continue 跳过剩余代码,继续下个迭代
break 跳出循环
return 会将整个脚本(或者函数)中断执行并返回,而不仅仅是跳出循环

4.2 while 循环

##  while true 无限循环,直到 sum 大于 1000 就 break 跳出
let sum = 1;
while true {
  sum = sum + sum;
  if sum > 1000 {
    break;
  }
}
println(sum);

5. 函数

5.1 函数库

函数库列表 https://www.yuque.com/boyan-avfmj/aviatorscript/ashevw

函数名称 说明
type(x) 返回参数 x 的类型,结果为字符串,如 string, long, double, bigint, decimal, function 等;Java 类则返回完整类名
string.length(s) 求字符串长度,返回 Long
string.startsWith(s1,s2) s1 是否以 s2 开始,返回 Boolean

5.2 函数的定义和调用

## 无需定义参数的类型以及返回值的类型,因为 AviatorScript 是动态类型系统,会根据实际传入和返回的类型自动转换
fn add(x, y) {
  return x + y;
}

three = add(1, 2);
println(three);

s = add('hello', ' world');
println(s);

5.3 匿名函数 lambda

语法 lambda (参数1,参数2...) -> 参数体表达式 end
定义一个匿名函数 lambda (x,y) -> x + y end

let three = (lambda (x,y) -> x + y end)(1, 2);
println(three);

匿名函数赋值给一个变量

let add = lambda (x,y) ->
  x + y 
end;

three = add(1, 2);
println(three);

6. 实战

6.1 示例一

引入依赖

<dependency>
    <groupId>com.googlecode.aviator</groupId>
    <artifactId>aviator</artifactId>
    <version>5.3.0</version>
</dependency>

在 resources 目录下新建文件aviator/hello.av,输入如下内容

println("hello, AviatorScript!");
@Test
public void test() throws IOException {
    Expression expression = AviatorEvaluator.getInstance().compileScript("aviator/hello.av");
    expression.execute();
}

说明:
AviatorScript 脚本源码文件约定以 .av 作为文件后缀
AviatorEvaluator.getInstance() 返回一个全局共享的 AviatorScript 引擎
compileScript(path) 编译脚本文件

6.2 示例二

@Test
public void test() {
    Long value = (Long) AviatorEvaluator.execute("1+2+3");

    Map<String, Object> map = new HashMap<>();
    map.put("name", "tinyspot");
    Object name = AviatorEvaluator.execute("name", map);

    String myName = "xing";
    Object newName = AviatorEvaluator.exec("'hello' + name11", myName);

    System.out.println(value);
}
@Test
public void testCustomAddFunction() {
    AviatorEvaluator.addFunction(new AddFunction());
    System.out.println(AviatorEvaluator.execute("add(10, 100)"));
}

// 自定义函数
public class AddFunction extends AbstractFunction {
    @Override
    public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
        Number left = FunctionUtils.getNumberValue(arg1, env);
        Number right = FunctionUtils.getNumberValue(arg2, env);
        return new AviatorDouble(left.doubleValue() + right.doubleValue());
    }

    @Override
    public String getName() {
        return "add";
    }
}

https://www.xamrdz.com/backend/3d61921758.html

相关文章: