这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战
MODULE_
在被加载模块中,可以通过 __MODULE__ 获取当前模块的信息,包括:
path,当前模块的代码路径exports,当前模块导出的函数或者变量列表。
只有被 load 或者 require 的模块才有这 exports 和 __MODULE__ 这两个特殊变量,其中 __MODULE__.exports 指向了 exports 。
因此可以直接赋值给 __MODULE__.exports 来整体导出一个方法列表:
## examples/module.av
## a test module
let m = seq.map();
m.add = lambda(x, y) ->
x + y
end;
m.sub = lambda(x, y) ->
x - y
end;
println("module path: " + __MODULE__.path);
__MODULE__.exports = m;
我们创建了一个 map 实例 m ,并给 m 设置了两个变量 m.add 和 m.sub 分别赋值了两个函数。最后将整个 m 赋值给了 __MODULE__.exports ,这样这个测试模块导出了两个方法 add 和 sub ,我们可以这样使用它们:
## examples/test_module.av
let t = require('examples/module.av');
println(t.add(1, 2));
println(t.sub(1, 2));
这样将打印:
module path: examples/module.av
3
-1
其中第一行是在 module.av 里打印的,而 3 和 -1 是分别执行 t.add(1, 2) 和 t.sub(1, 2) 的结果。
请注意,不要直接去执行 module.av 文件,它只能被引用并使用,如果你直接执行将报错:
Exception in thread "main" com.googlecode.aviator.exception.ExpressionRuntimeException: Could not find variable __MODULE__.path
at com.googlecode.aviator.runtime.type.AviatorJavaType.getProperty(AviatorJavaType.java:405)
at com.googlecode.aviator.runtime.type.AviatorJavaType.getValueFromEnv(AviatorJavaType.java:316)
at com.googlecode.aviator.runtime.type.AviatorJavaType.getValue(AviatorJavaType.java:308)
at com.googlecode.aviator.runtime.type.AviatorString.add(AviatorString.java:58)
at Script_1586622095774_0/931919113.execute0(Unknown Source)
at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:92)
at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:144)
at com.googlecode.aviator.example.RunScriptExample.main(RunScriptExample.java:19)
数组和集合
数组
Tuple
tuple 函数可以创建一个固定大小的数组,等价 java 的类型为 Object [] :
## examples/tuple.av
let t = tuple(1, 2, "hello", 3.14);
println("type of t: " + type(t));
for x in t {
println(x);
}
println("count of t: "+ count(t));
println("t[0] = " + t[0]);
t[0] = 100;
println("t[0] = " + t[0]);
这个例子演示了 tuple 的基本操作: for 用来遍历数组, count 可以获取数组长度, t[x] 可以访问索引位置 x 的元素,同样也可以赋值特定位置的元素:
type of t: Object[]
1
2
hello
3.14
count of t: 4
t[0] = 1
t[0] = 100
tuple 可以放入任意类型的元素,如果要创建特定类型的,就需要用到其他函数。
创建类型数组并填充
可以通过 seq.array(type, ..args) 可以创建 type 类型的数组:
## examples/array.av
let a = seq.array(int, 1, 2, 3, 4);
println("type(a) is : " + type(a));
println("count(a) is: " + count(a));
比如上面创建了一个 int[] 数组,他的长度是 4,元素分别为 1, 2, 3, 4 。
如果传入错误的类型,创建将报错:
let a = seq.array(int, 1, 2, "hello", 4);
报错 Unexpected param type, expected: int, given: java.lang.String 。
但是如果可以转化为目标类型,比如 double 可以转成 int ,那么还是可以创建的:
let a = seq.array(int, 1, 2, 3.3, 4);
map(a, println)
3.3 将被转为 3:
1
2
3
4
seq.array 的 type 可以是基本类型,如 short 、 byte 、 char 、 bool 、 float 、 double 、 int 、 long 以及 void 。
也可以是对象,但是需要给完整的类名,比如创建字符串数组:
let s = seq.array(java.lang.String, "hello", "world", "aviator");
println(string.join(s, ","));
string.join 函数将第一个参数的字符串集合用第二个参数的字符串起来,这里将输出 hello,world,aviator 。
创建空数组
如果要创建一个“空”数组,只确定类型和长度,可以用 seq.array_of(type, len) ,这样就创建了一个 type[len] 的数组,每个元素都将是该类型的默认值,比如整数就是 0,对象就是 null:
let a = let a = seq.array_of(int, 3);
println("type(a) is : " + type(a));
println("count(a) is: " + count(a));
println("before assignment:");
for x in a {
println(x);
}
for i in range(0, 3) {
a[i] = i;
}
println("after assignment:");
for x in a {
println(x);
}
输出:
type(a) is : int[]
count(a) is: 3
before assignment:
0
0
0
after assignment:
0
1
2
创建多维数组
seq.array_of(Class, &dimensions) 也可以用于创建多维数组,举例来说:
## create multidimensional array
let a = seq.array_of(long, 3, 2);
assert(3 == count(a));
assert(2 == count(a[0]));
let x = 0;
for i in range(0, 3) {
for j in range(0, 2) {
a[i][j] = x;
x = x + 1;
}
}
for i in range(0, 3) {
for j in range(0, 2) {
p("a[#{i}][#{j}] = #{a[i][j]}");
}
}
我们创建了一个 2 x 3 的二维数组,并遍历初始化,最终打印数组:
a[0][0] = 0
a[0][1] = 1
a[1][0] = 2
a[1][1] = 3
a[2][0] = 4
a[2][1] = 5