struct类型
struct类型可以很方便的把相关数据组织在一起,增加代码的可读性和便利性。 struct类型和array数组类型的差别:
- 没有大小写问题。
- 写起来更方便。
- 代码可读性更强。
- 支持绑定self,相当于可以自由动态定义的class。
语法
除了可以用struct()来构造struct类型外,还提供更方便的$[]
语法糖来初始struct。
a := 100;
st := $[
a : a,
b : 2,
c : 3,
t : array(1,2,3),
x : $[
y : 1,
z : 2
]
];
st 相当于 struct(a:100,b:2,c:3,t:array(1,2,3),x:struct(y:1,z:2))
也可以是$[]:
st := $[];
st 相当于 struct()
函数如何绑定self
方法:把函数的第一个参数定义成self,否则在使用self会报编译错误。struct调用函数的时候,会把自己做为第一个参数传递进去,这样就非常巧妙的解决了self的绑定问题。 例如:
st := $[
data: "100",
fun: function (self,x,y,z) begin
vprintln("=>", x,y,z);
return self.data;
end,
fun2: FindFunction("ClsMethod"),
(* 如果第一个参数不是self而又使用了self,编译会报错。
fun3: function (x,y,z) begin
vprintln("=>", x,y,z);
return self.data;
end,
*)
// 如果没有使用self可以不定义self。
fun4: function (x,y,z) begin
vprintln("=>", x,y,z);
return "200";
end,
// 子结构的self也能绑定到子结构本身。
child: $[
data: "300",
fun5: function (self,x,y,z) begin
vprintln("child=>", x,y,z);
return self.data;
end
]
];
x := st.fun(1,2,3);
vprintln("fun", x);
x := st.fun2(4,5,6);
vprintln("fun2", x);
x := st.fun4(7,8,9);
vprintln("fun4", x);
x := st.child.fun5(8,9,10);
vprintln("fun5", x);
(*
打印:
=> 1 2 3
fun 100
=> 4 5 6
fun2 100
=> 7 8 9
fun4 200
child=> 8 9 10
fun5 300
*)
(* 如果第一个参数不是self而又使用了self,编译会报错。
function NotClsMethod(x,y,z)
begin
return self.data;
end;
*)
// 这样同样可以工作
function ClsMethod(self,x,y,z)
begin
vprintln("=>", x,y,z);
return self.data;
end;
由于TSL语言中已经用$
来做字符串连接,用["字段名"]
在select查询中代表字段,所以在语法解析中做相应的判断,确保原来的语法可以正常工作,没有兼容性问题。
例如,下面的语句是可以正常工作的,没有问题:
提供的方法
struct()
struct()
: 构造struct类型。
- 参数列表
无
- 返回值
struct对象
- 例子
st := struct();
st.a := 100;
st.b := 2.0;
st.c := "ok";
st.t := array(1,2,3);
st.x := struct();
st.x.y := 1;
struct_attrs
struct_attrs(st)
: 返回struct类型的所有属性名的列表。
-
参数列表
参数 描述 st struct对象 -
返回值
字符串数组。
- 例子
st := struct();
st.a := 100;
st.b := 2.0;
st.c := "ok";
st.t := array(1,2,3);
st.x := struct();
st.x.y := 1;
vprintln(struct_attrs(st));
打印:
array("a","b","c","t","x")
struct_check
struct_check(st)
: 检查是否struct类型。
-
参数列表
参数 描述 st struct对象 -
返回值
Bool。
- 例子
struct_dump
struct_dump(st)
: 把struct类型的转换成字符串。
-
参数列表
参数 描述 st struct对象 -
返回值
字符串。
- 例子
st := struct();
st.a := 100;
st.b := 2.0;
st.c := "ok";
st.t := array(1,2,3);
st.x := struct();
st.x.y := 1;
vprintln(struct_dump(st));
打印:
struct(a:100,b:2.0,c:"ok",t:array(1,2,3),x:struct(y:1))
struct_empty
struct_empty(st)
: 检查是否struct是否是空,等同于 st = $[]
。
-
参数列表
参数 描述 st struct对象 -
返回值
Bool。
- 例子
struct_has
struct_has(st, attr)
: 检查struct类型是否有指定的属性。
-
参数列表
参数 描述 st struct对象 attr 属性名称 -
返回值
bool类型。
- 例子
st := struct();
st.a := 100;
x := struct_has(st, 'a'); // x = True
y := struct_has(st, 'b'); // y = False
struct_get
struct_get(st, attr)
: 获取struct指定的属性的值。
-
参数列表
参数 描述 st struct对象 attr 属性名称 -
返回值
数组类型,如果发生错误:
下标 值 0 错误代码 1 错误信息 没有错误:
下标 值 0 0 1 返回的数据内容 -
例子
st := struct();
st.a := 100;
[err, x] := struct_get(st, 'a'); // x = array(0, 'a')
[err, y] := struct_get(st, 'b'); // y = array(-1, 错误信息)
struct_set
struct_set(st, attr, value)
: 设置struct指定的属性的值。
-
参数列表
参数 描述 st struct对象 attr 属性名称 value 值 -
返回值
无
-
例子
st := struct();
st.a := 100;
struct_set(st, 'b', 101);
[err, x] := struct_get(st, 'b'); // x = array(0, 101)
struct_pack
struct_pack(st)
: 把struct类型的输出成binary数据,方便保存和传输。
-
参数列表
参数 描述 st struct对象 -
返回值
binary类型。
- 例子
st := struct();
st.a := 100;
st.b := 2.0;
st.c := "ok";
st.t := array(1,2,3);
st.x := struct();
st.x.y := 1;
s := struct_pack(st));
st2 := struct_unpack(s);
same := struct_dump(st) = struct_dump(st2); // same = True
struct_unpack
struct_unpack(s)
: 把struct_pack输出的binary数据再转成struct类型。
-
参数列表
参数 描述 s binary类型 -
返回值
struct类型。
- 例子
st := struct();
st.a := 100;
st.b := 2.0;
st.c := "ok";
st.t := array(1,2,3);
st.x := struct();
st.x.y := 1;
s := struct_pack(st));
st2 := struct_unpack(s);
same := struct_dump(st) = struct_dump(st2); // same = True
struct_asarray
struct_asarray(st)
: 把struct_pack转换成array数组类型。
-
参数列表
参数 描述 st struct对象 -
返回值
array类型。
- 例子
st := struct();
st.a := 100;
st.b := 2.0;
st.c := "ok";
st.t := array(1,2,3);
st.x := struct();
st.x.y := 1;
a := struct_asarray(st);
vprintln(a);
打印:
array("a":100,"b":2.0,"c":"ok","t":(1,2,3),"x":("y":1))
struct类型的使用例子
把相关的数据放在一起
例如可以提供rhq_st、md_st或者basic_st等函数,可以把一列数据做为struct一次返回回来,以方便使用。
传递参数
struct可以用来传递任意多的参数,使用$[]
语法会超级方便,例如:
users := find_user(db, $[ role: 'admin', dept: array('信息部', '交易部') ]);
function find_user(db, cond);
begin
if struct_has(cond, 'role') then ...
if struct_has(cond, 'user') then ...
if struct_has(cond, 'dept') then ...
....
end;
相当于类似Python等语言的命名参数的作用,使用它可以帮助设计出更方便、更好用的函数接口。
返回值应用
struct可以很方便返回任意多的结果值。下面是一个很高级的例子:
// 定义fitler算法函数
filter := (self, cond) => $[
iter: self,
cond: cond,
next: (self) => begin
while true do begin
v := self.iter.next();
if v.finished then return v;
if self.cond(v.value) then return v;
end
end
];
// 定义zip函数
zip := (self, a, b) =>
begin
st:= $[
a: a,
b: b,
ix: 0,
len: max(length(a), length(b)),
next: (self) => begin
if self.ix >= self.len then
return $[ finished: true ];
else
begin
value := array(self.a[self.ix], self.b[self.ix]);
self.ix := self.ix + 1;
return $[ finished: false, value: value ];
end
end,
];
mixin(st, self.algorithm); // 合并算法
return st;
end;
// 组装成iter
iter := $[
zip: zip,
algorithm: $[
filter: filter,
]
];
a := array('a', 'b', 'c');
b := array(1,2,3);
for x in iter.zip(a, b).filter((x) => x[0]='a') do
println("x={}", x);
(*
打印:
x=array("a",1)
*)
function mixin(a, b)
begin
for attr in array_iter(struct_attrs(b)) do
if [err, v] := struct_get(b, attr) then
raise v;
else
struct_set(a, attr, v);
return a;
end;
function array_iter(a)
begin
return $[
a: a,
ix: 0,
len: length(a),
next: (self) => begin
if self.ix >= self.len then
return $[ finished: true ];
else
begin
value := self.a[self.ix];
self.ix++;
return $[ finished: false, value: value ];
end
end
]
end;
$[finished, value]
这个结构,就可以利用相应的算法。这就是泛型编程(Generic Programming)。