跳转至

()=>定义匿名函数

语法

( 参数列表 ) => 函数体

  • 如果函数体有多行,必须用beginend
  • 如果只有单行,可以不需要beginend,还可以省略return

范例

基础语法

func1 := () => begin return 1; end;
func2 := () => return 2;
func3 := () => 3;
func4 := (x) => x+1;
func5 := (x,y) => x+y;

应用

定义iter并提供算法。

// 定义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;

函数如何绑定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;