killme2008 / aviatorscript

A high performance scripting language hosted on the JVM.
http://fnil.net/aviator/
4.53k stars 841 forks source link

表达式执行结果不符合预期 #384

Closed archervanderwaal closed 3 years ago

archervanderwaal commented 3 years ago

自定义一个函数,统计参数为true的个数

public class CountTrueFunction extends AbstractVariadicFunction {

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

    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        try {
            if (ArrayUtils.isEmpty(args)) {
                return AviatorLong.valueOf(0);
            }
            long cnt = Arrays.stream(args)
                .filter(arg -> arg instanceof AviatorBoolean)
                .filter(AviatorBoolean.TRUE::equals).count();
            return AviatorLong.valueOf(cnt);
        } catch (Exception e) {
            ErrorHelper.reportAllExceptions("aviator-custom-function", "mtsi.countTrue-" + e.getClass().getSimpleName());
            throw e;
        }
    }
}

测试如下

public static void main(String[] args) {
        AviatorEvaluator.addFunction(new CountTrueFunction());
        String exp = "countTrue(a, b)";
        Expression expression = AviatorEvaluator.compile(exp);
        Map<String, Object> env = Maps.newHashMap();
        env.put("a", true);
        env.put("b", true);
        System.out.println(expression.execute(env)); // output => 0

        exp = "countTrue(a == true, b == true)";
        expression = AviatorEvaluator.compile(exp);
        env = Maps.newHashMap();
        env.put("a", true);
        env.put("b", true);
        System.out.println(expression.execute(env)); // output => 2
    }
killme2008 commented 3 years ago

这是你函数实现问题,传入的 args 不一定是 AviatorBoolean 类型,他可能是一个 java 变量,你真正要做的比较是每个 arg.getValue(env) 的结果为 true。

archervanderwaal commented 3 years ago

这是你函数实现问题,传入的 args 不一定是 AviatorBoolean 类型,他可能是一个 java 变量,你真正要做的比较是每个 arg.getValue(env) 的结果为 true。

了解