aviatorscript
aviatorscript copied to clipboard
增加 in 运算符支持
see: #208
in
运算符检查右侧数组以查看它是否包含等于左侧值的值。 相等性由 == 运算符的使用确定。
比如
表达式 sub.Name in (obj.Admins)
数据 sub{Name: "alice"}, obj{Name: "a book", Admins: {"alice", "bob"}}
感谢!
用现有函数就支持的,不需要引入特殊的操作符:
seq.some(obj.Admins, fn(x) { x.Name == sub.Name})
@killme2008 我尝试使用seq.some(obj.Admins, fn(x) { x.Name == sub.Name}),但似乎编译时识别不了obj.Admins这种形式,只能识别Admins。我不知道它能不能自动获取obj对象中的Admins属性?
我编译可以的,你确定不行吗?
Expression result =
AviatorEvaluator.compile("seq.some(obj.Admins, fn(x) { x.Name == sub.Name})");
System.out.println(result);
输出:
Script_1626251523203_58/824318946@377dca04
@killme2008 编译不会直接抛出异常,但debug会显示异常,且结果不正确,我做了一个例子你看一下
class Sub{
public String Name;
}
class Admins{
public String Name;
}
class Obj{
public Admins[] Admins;
}
Sub sub = new Sub();
sub.Name="alice";
Obj obj = new Obj();
Admins admin1 = new Admins();
admin1.Name="alice";
Admins admin2 = new Admins();
admin2.Name = "bob";
Admins[] admins = new Admins[]{admin1,admin2};
obj.Admins=admins;
//obj.Admins,编译不会抛出异常,但debug会显示f0-Method threw 'com.googlecode.aviator.exception.ExpressionRuntimeException' exception. Cannot evaluate com.googlecode.aviator.runtime.type.AviatorJavaType.toString()
Expression ex = AviatorEvaluator.compile("seq.some(obj.Admins, fn(x) {x.Name == sub.Name})");
System.out.println(ex);
Map<String,Object> map = new HashMap<>();
map.put("sub",sub);
map.put("obj",obj);
//o 为null
Object o = ex.execute(map);
//改为Admins,不会显示异常
Expression ex2 = AviatorEvaluator.compile("seq.some(Admins, fn(x) {x.Name == sub.Name})");
System.out.println(ex2);
Map<String,Object> map2 = new HashMap<>();
map2.put("sub",sub);
map2.put("Admins",admins);
//结果正常,查出来o2 为alice
Object o2 = ex2.execute(map2);
请实现 getter/setter
请实现 getter/setter
ok,看起来是个低级错误,不好意思。被debug变量显示的异常误导了
这里我看了下,按理说应该报错的,似乎将异常吞没了,原来设定是抛一个 property not found 的异常,我检查下。
不过 public field 似乎是可以支持下的,减少 getter/setter 的繁琐代码。
目前这个 dot 语法糖支持的是 getter/setter 或者 java.util.Map#get ,以及 List 和数组的 get(i)
ok,我没有考虑dot这个语法糖的实现方式,默认认为了public可以访问。但为什么第二个例子中sub.name却能访问,也没有getter,第二个例子却能得到正确结果
是因为两个取值都是 null 了,你把 admin 的数组调换下顺序,结果就是 bob 了。这是个陷阱,抛异常是更合理的。
已在 5.2.7 分支修复,谢谢反馈
https://github.com/killme2008/aviatorscript/pull/396/commits/ac3122fa670db29a38ff6214c894d0605a26ecea
当时测试考虑了应该把alice放后面,后来忽略了。谢谢持续关注,我的问题应该能解决了
@killme2008 不好意思,还有一个问题。现在我用obj.Admins,无论有无getter,debug都会有异常,但可以得到正确结果。你刚才说这里应该抛出异常,但如果这样,我就无法正#常使用了,请问这里你是如何修复更新的
没有 getter 是不可能得到正确值的,目前的反射实现是基于 getter
debug 异常是另一个问题,会单独修复
计划引入 in 操作符
计划引入 in 操作符
考虑将('alice','bob')这种形式识别为数组吗?配合in使用,比如 alice in (alice,bob),我们的项目有这种需求
不会,不准备搞集合的 literal 语法,你需要自己加下函数调用 alice in tuple(alice, bob)
不会,不准备搞集合的 literal 语法,你需要自己加下函数调用
alice in tuple(alice, bob)
那期待in的原生支持
用现有函数就支持的,不需要引入特殊的操作符:
seq.some(obj.Admins, fn(x) { x.Name == sub.Name})
这里我也短路了,也不需要用闭包,默认用 include 函数就可以了:
include(obj.Admins, sub.Name);
@killme2008 请问这个支持实现了吗?还是又删除了?
@tangyang9464 在现有代码上的实现会有缺陷,暂时放弃了,还是先准备做大版本重构。