发信人: jinna@phoenix (吉娜), 信区: mud
标  题: LPC 的函数 -- 1 (from wade@Fantasy.Space)
发信站: 交大资工凤凰城资讯站 (Thu May 16 21:44:37 1996)
转信站: phoenix
Origin: sleepy.ice.ntnu.edu.tw

function 指标与其变数型态
-------------------------

    LPC 提供了 function 这种变数型态, 可以用来方便的指向函数.
  也许你会想要把函数传给某些 efun, 例如某些过滤的函数. 函数的
  指标可以用 (: 函数名称 :) 来引用, 配合函数变数则:

        function f = (: local_func :);

    你可以把 f 当成变数传给其它函数, 或者是把它当成函数指标:

        foo(f);                         // 当成变数.
        map_array( ({ 1, 2 }), f);      // 当成指标.

    或者, 有一个更强的用法, 在后来的时机里再"求值":

        x = evaluate(f, "hi");

When the last line is run, the function that f points to is called, and "hi"
is passed to it.  This will create the same effect as if you had done:
    执行到上一行的时候, 实际上会呼叫 f 所指的函数去, 并传 "hi" 给它当参数.
  上面的方式跟下面的程式码意义相同:

        x = local_func("hi");

    以函数变数来指向函数的好处是, 你可以改变指标, 让它指向别的函数.
  尤其是配合 evaluate() 时, 在此, 先提醒一下, 如果传给 evaluate() 的
  参数不是函数指标的话, 会传回它的值, 因此下列方式可见函数变数的优点:

        void set_short(mixed x) { short = x; }
        mixed query_short() { return evaluate(short); }

    如上面的宣告, 你可以如下的使用 set_short():
        set_short("Whatever");
        set_short( (: short_func :) );

    如此一来, 物件可以自己定义 short_func(), 可增加许多弹性.


各种函数变数或指标
------------------

    最简单的函数指标的使用已经如上所述, 即: (: 函数名称 :), 这种
  方式可以方便的用在同一物件的函数上, 也可以把参数包括进来, 如:

        string foo(string a, string b)
        {
          return "(" + a "," + b + ")";
        }

        void create()
        {
          function f = (: foo, "left" :);

          printf( "%s %s\n", evaluate(f), evaluate(f, "right") );
        }

        ==> 结果: (left,0) (left,right)


    第二种用法是 efun 指标, 跟同一物件里的局部函数指标很类似. 例如:
  objects() 会传回所有 mud 载入的物件, 只要该物件满足某函数, 如:

        objects( (: clonep :) )

  因为所有物件都是 "clonep", 也就是, 所有物件 ob->clonep() 都传回非 0 值,
  因此上述例子会传回所有的物件阵列.

    底下再示范一个例子:

        void create()
        {
          int i;
          function f = (: write, "Hello, world!\n" :);

          for (i=0; i<3; i++) { evaluate(f); }
        }

    结果是:
        Hello, world!
        Hello, world!
        Hello, world!

    simul_efun 会跟 efun 一样的效果(否则怎会称为 simul_efun?!).
    而 efun 会跟局部的函数很像, 是因为 efun 是整体性的函数, 因此
  可以想成是跟局部的函数同样地位.

    第三种型式的是 call_other 函数指标. 它很类似于 MudOS 所支援的函数
  指标的用法, 格式是:

        (: 物件, 函数名称 :)

  假如有参数的话, 可以把所有参数组成阵列加在函数名称之后. 例如:

        void create()
        {
          string *ret;
          function f = (: this_player(), "query" :);

          ret = map( ({ "name", "short", "long" }), f );
          write(implode(ret, "\n"));
        }

    上面的程式片断相当于:
        this_player()->query("name");
        this_player()->query("short");
        this_player()->query("long");

    如果要让函数指标直接指向 query("short") 的话, 可以是:

        f = (: this_player(), ({ "query", "short" }) :)

    底下的例子跟上面的一模一样, 供你做参考:

        f = (: call_other, this_player(), "query", "short" :)
        // 透过指向 call_other efun, 来呼叫定义在 this_player() 物件中
        // 的 query("short")


--

  本份文件获 TMI 授权翻译并转载



