-
Notifications
You must be signed in to change notification settings - Fork 817
完整选项列表说明
Options
支持一些功能的自定义选项,详解如下。
优化级别,更精确地说是运行的优化倾向,可以是:
-
AviatorEvaluator.EVAL
,默认值,以运行时的性能优先,编译会花费更多时间做优化,目前会做一些常量折叠、公共变量提取的优化。适合长期运行的表达式。 -
AviatorEvaluator.COMPILE
,以编译的性能优先,不会做任何编译优化,牺牲一定的运行性能,适合需要频繁编译表达式的场景。
Decimal 数字类型的运算精度,默认是 java.util.MathContext.DECIMAL128
。
是否将所有浮点数解析为 Decimal 类型,适合需要高精度运算的场景,并且不想为每个浮点数字指定 M
后缀(表示 Decimal 类型)。默认为 false 不开启。
是否跟踪运行,打开后将在控制台打印整个表达式的求值过程。请勿在生产环境打开,将极大地降低性能。默认为 false 关闭。
表示正则匹配的时候,是否将捕获的分组放入 env 环境中,例如
email=~/([\\w0-8]+)@\\w+[\\.\\w+]+/ ? $1:'unknow'
将 email 变量中的用户名部分(@ 符号之前)匹配出来,并放到 $1
变量中,如果关闭 PUT_CAPTURING_GROUPS_INTO_ENV
(设置为 false),将不会将捕获的分组放入 env,也就无法获取到匹配的分组。默认为 true 开启。
是否启用变量访问的语法糖,默认情况下 Aviator 会通过 commons-beantuils 反射访问类似 a.b.c
这样的嵌套 JavaBean 变量,或者 #list.[0].name
这样的数组(链表)中的元素。但是部分用户可能想关闭这个行为,强制都从 env 中获取这些变量值,那么就可以将该选项关闭,也就是设置为 false。默认为 true 开启。
在启用变量访问糖的情况下,如果反射调用失败,默认的行为将抛出运行时异常,而不是返回 null。可以通过本选项改变这个行为,启用的情况下(也就是设置为 true),将不抛出异常,而是返回 null。 默认为 false 关闭。
从 4.0 开始,为了支持 lambda, aviator 引入了变量作用域 scope 的概念,本来的默认行为是不再修改用户传入的 env
对象,但是后面看到比较多的用户依赖这个行为,因此提供了这个新选项 USE_USER_ENV_AS_TOP_ENV_DIRECTLY
,当为 true 的时候就会将用户传入的 env
作为最顶层的作用域 scope 来使用,并且默认为 true 启用。如果你不需要 aviator 产生副作用污染你传入的 env
,这个选项更推荐设置为 false
。
从 4.1.0 开始, aviator 支持赋值,但是在一些场景下可能因为安全的原因,比如你有一个校验函数 validate(x)
,如果允许赋值,用户可以覆盖这个函数来绕过校验:
validate = lambda(x) -> true end ; validate(x)
如果表达式是用户传入不可控制,建议关闭赋值功能,将 Options.DISABLE_ASSIGNMENT
设置为 true
即可,默认不关闭。
是否将整型数字都解析为 BigDecimal,默认为 false,也就是不启用。在所有数字都是需要高精度计算的场景,启用该选项可以减少一些类型转换。
是否捕获函数调用点的参数列表,如果启用,那么类似 func
这样的自定义函数:
func(a, b, c, 100+2)
这样的表达式,就可以在 func 内得到调用的参数列表,
@Override
public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
final AviatorObject arg2, final AviatorObject arg3, final AviatorObject arg4) {
List<FunctionArgument> args = FunctionUtils.getFunctionArguments(env);
......
}
得到的 args 就是参数列表:
[FunctionArgument, index=0, expression="a"]
[FunctionArgument, index=1, expression="b"]
[FunctionArgument, index=2, expression="c"]
[FunctionArgument, index=3, expression="100+2"]
在 lambda 中也可以捕获,捕获的调用参数列表存放在 __args__
变量:
List<FunctionArgument> args = (List<FunctionArgument>) AviatorEvaluator
.execute("f = lambda(a,bc, d) -> __args__ end; f(1,2,100+2)");
assertEquals(3, args.size());
System.out.println(args);
assertEquals(0, args.get(0).getIndex());
assertEquals("1", args.get(0).getExpression());
assertEquals(1, args.get(1).getIndex());
assertEquals("2", args.get(1).getExpression());
assertEquals(2, args.get(2).getIndex());
assertEquals("100+2", args.get(2).getExpression());
利用这一特性,你可以在运行时对调用的参数做参数校验或者分支派发,以及对于函数调用过程做优化,例如对针对参数做结果缓存等等。