⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.html

📁 Mud os datasheet No password
💻 HTML
字号:
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=bg2312">
   <META NAME="Author" CONTENT="Spock">
   <META NAME="GENERATOR" CONTENT="Mozilla/4.01 [en] (Win95; I) [Netscape]">
   <TITLE>MudOS v21c2 参考文件 - lpc - types - function</TITLE>
</HEAD>
<BODY TEXT="#CCFFFF" BGCOLOR="#000000" LINK="#33FF33" VLINK="#FF0000" ALINK="#33CCFF" BACKGROUND="../../../image/ff/fftitleback.jpg" NOSAVE>

<CENTER>
<H1>
<FONT COLOR="#FF99FF">function</FONT></H1></CENTER>

<CENTER>
<HR WIDTH="100%"></CENTER>

<CENTER><FONT COLOR="#FFFFCC">一般概念 :</FONT></CENTER>

<HR WIDTH="100%">

<P>MudOS 有一种称为 function  (函数指针) 的变量类型. 这种类型的变量可以用来指向各种不同的函数.
您也许早已熟悉把一个函数当作某些外部函数 (efuns)  参数. 举例来说, 像是过滤数组的外部函数.
它读入一个数组, 并经由一个函数过滤数组中的元素. 让此函数返回非零值 (non-zero)
的元素就保留下来, 结果返回一个新的数组. 传统上, 这样做要传入一个物件和函数的名称.
现在, 可以用函数指针这种变量类型做到. 函数指针只含有一个函数的信息, 可以在稍后执行其函数.

<P>函数指针可以创造并指定为变量:
<UL><FONT COLOR="#FFCC99">function f = (: local_func :);</FONT></UL>
上面的 f  可以用于其他程序流程或外部函数中, 如同普通的变量值:
<UL><FONT COLOR="#99FF99">foo(f);  map_array( ({ 1, 2 }), f);</FONT></UL>
或是稍后再执行 f:
<UL><FONT COLOR="#99FF99">x = evaluate(f, "hi");</FONT></UL>
上一行执行时, 会调用 f  指向的函数, 而 "hi" 当成参数传入函数. 其效果同下:
<UL><FONT COLOR="#99FF99">x = local_func("hi");</FONT></UL>
使用函数指针的好处是, 如果您想使用不同的函数, 只需要改变函数指针变量的值.

<P>注意 evaluate() 的参数如果不是函数, 就只会返回参数值. 所以您可以做以下的
<BR>事:
<UL><FONT COLOR="#99FF99">void set_short(mixed x) { short = x; }</FONT>
<BR><FONT COLOR="#99FF99">mixed query_short() { return evaluate(short);
}</FONT></UL>
这样, 简单的物件可以只用 set_short("Whatever"); 以达成
<BR>set_short( (: short_func :) ); 的效果.

<P>
<HR WIDTH="100%">
<CENTER><FONT COLOR="#FFFFCC">目前函数指针的种类 :</FONT></CENTER>

<HR WIDTH="100%">

<P>最简单的函数指针如上面所述. 只是简单地指向同一个物件中的一个局部函数
(local function), 即 (: function_name :). 函数指针的值可以包括函数的参数,
例如:
<UL><FONT COLOR="#99FF99">string foo( string a, string b ) {</FONT>
<UL><FONT COLOR="#99FF99">return "(" + a "," + b + ")";</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>

<UL><FONT COLOR="#99FF99">void create() {</FONT>
<UL><FONT COLOR="#99FF99">function f = (: foo, "left" :);</FONT>
<BR><FONT COLOR="#99FF99">printf( "%s %s\n", evaluate(f), evaluate(f, "right")
);</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>
会印出:<FONT COLOR="#FFCCFF"> (left,0) (left,right)</FONT>

<P>
<HR WIDTH="100%">

<P>第二种的函数指针是外部函数指针, 就是 (: efun_name :). 这样与局部函数指针很类似.
譬如说, objects() 外部函数要传入函数, 并返回任何使函数为真值的物件. 所以:
<UL><FONT COLOR="#FFCC99">objects( (: clonep :) )</FONT></UL>
会返回游戏中所有的复制物件 (clones). 您也可以使用参数:
<BR> 
<UL><FONT COLOR="#99FF99">void create() {</FONT>
<UL><FONT COLOR="#99FF99">int i;</FONT>
<BR><FONT COLOR="#99FF99">function f = (: write, "Hello, world!\n" :);</FONT>

<P><FONT COLOR="#99FF99">for (i=0; i&lt;3; i++) { evaluate(f); }</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>
就会印出:

<P><FONT COLOR="#FFCCFF">Hello, world!</FONT>
<BR><FONT COLOR="#FFCCFF">Hello, world!</FONT>
<BR><FONT COLOR="#FFCCFF">Hello, world!</FONT>

<P>注意, 对函数指针来说, simul_efuns  (模拟外部函数) 与外部函数是相同的.

<P>
<HR WIDTH="100%">

<P>第三种形式是 call_other 函数指针, 与以前 MudOS  所使用的函数指针类型类似.
其形式为 (: object, function :).  要使用参数的话, 应将函数名称与参数的数组并用.
以下是范例:
<BR> 
<UL><FONT COLOR="#99FF99">void create()</FONT>
<BR><FONT COLOR="#99FF99">{</FONT>
<UL><FONT COLOR="#99FF99">string *ret;</FONT>
<BR><FONT COLOR="#99FF99">function f = (: this_player(), "query" :);</FONT>

<P><FONT COLOR="#99FF99">ret = map( ({ "name", "short", "long" }), f );</FONT>
<BR><FONT COLOR="#99FF99">write(implode(ret, "\n"));</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>
这样会印出与 <FONT COLOR="#99FF99">this_player()->query("name"), this_player()->query("short"),</FONT>
<BR><FONT COLOR="#99FF99">和 this_player()->query("long")</FONT> 相同的结果.

<P>要使一个函数指针直接调用 query("short") :
<UL><FONT COLOR="#99FF99">f = (: this_player(), ({ "query", "short" })
:)</FONT></UL>
以下是达到同样目的的做法参考:
<UL><FONT COLOR="#99FF99">f = (: call_other, this_player(), "query", "short"
:)        </FONT>/* 一个外部函数指针, 使用 call_other */
<BR><FONT COLOR="#99FF99">f = (: this_player()->query("short") :)       
</FONT>// 有效的运算式; 请见下文.</UL>

<HR WIDTH="100%">

<P>第四种形式是运算式 (expression) 函数指针. 就是 (: 运算式 :).  在一个运算式函数指针中,
参数可以用 $1, $2, $3 ... 代表, 举例如下:
<UL><FONT COLOR="#99FF99">evaluate( (: $1 + $2 :), 3, 4)       
</FONT>// 返回 7.</UL>
这可以用于 sort_array, 范例如下:
<UL><FONT COLOR="#99FF99">top_ten = sort_array( player_list,</FONT></UL>

<UL>
<UL><FONT COLOR="#99FF99">(: $2->query_level() - $1->query_level :) )[0..9];</FONT></UL>
</UL>

<HR WIDTH="100%">
<BR>第五种形式是不知名 (anonymous)  函数:
<BR> 
<UL><FONT COLOR="#99FF99">void create() {</FONT>
<UL><FONT COLOR="#99FF99">function f = function(int x) {</FONT>
<UL><FONT COLOR="#99FF99">int y;</FONT>

<P><FONT COLOR="#99FF99">switch(x) {</FONT>
<UL><FONT COLOR="#99FF99">case 1: y = 3;</FONT>
<BR><FONT COLOR="#99FF99">case 2: y = 5;</FONT></UL>
<FONT COLOR="#99FF99">}</FONT>
<BR><FONT COLOR="#99FF99">return y - 2;</FONT></UL>
<FONT COLOR="#99FF99">    };</FONT>

<P><FONT COLOR="#99FF99">printf("%i %i %i\n", (*f)(1), (*f)(2), (*f)(3));</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>
会印出: <FONT COLOR="#FFCCCC">1 3 -2</FONT>

<P>注意, (*f)(...) 等于 evaluate(f, ...) , 保留这种语法是为了与旧版相容.
任何普通函数合法 (legal)  的写法, 都可以用于不知名函数.

<P>
<HR WIDTH="100%">
<CENTER><FONT COLOR="#FFFFCC">什么时候执行 (evaluate) 函数 ?</FONT></CENTER>

<HR WIDTH="100%">

<P>创造带有参数的外部函数、局部函数、模拟外部函数指针时, 会执行函数. 而运算式和功能性
(functional) 函数指针, 只有在使用函数指针时执行函数:
<UL><FONT COLOR="#99FF99">(: destruct, this_player() :)        </FONT>/*
创造这个函数指针时, 就会摧毁 this_player(). 函数于创造时执行. */
<BR><FONT COLOR="#99FF99">(: destruct(this_player()) :)        </FONT>/*
在稍后使用此函数指针时, 才会摧毁 this_player()" */</UL>
在此, 不可以在运算式函数指针里, 使用一个局部变量. 因为执行这个函数指针之后,
这个局部变量就不存在了. 但是可以用下面这个方法解决:
<UL><FONT COLOR="#99FF99">(: destruct( $(this_player) ) :)       
</FONT>// 与上面第一个范例相同.</UL>
$(whatever) 表示要执行 whatever, 并保留其值. 当执行此函数时, 再传入这个值.
这样一来可以更有效率:
<UL><FONT COLOR="#99FF99">map_array(listeners,</FONT>
<UL><FONT COLOR="#99FF99">(: tell_object($1, $(this_player()->query_name())
+ " bows.\n") :) );</FONT></UL>
</UL>
只做一次 call_other , 而不需要每个消息都做. 也可以事先合并字符串:
<UL><FONT COLOR="#99FF99">map_array(listeners,</FONT>
<UL><FONT COLOR="#99FF99">(: tell_object($1, $(this_player()->query_name()
+ " bows.\n")) :) );</FONT></UL>
</UL>
注意, 在这个情形下, 也可以这样做:
<UL><FONT COLOR="#99FF99">map_array(listeners,</FONT>
<UL><FONT COLOR="#99FF99">(: tell_object, this_player()->query_name() +
" bows.\n" :) );</FONT></UL>
</UL>

<CENTER>
<HR WIDTH="100%"><FONT COLOR="#FFFFCC">翻译: Spock @ FF 97.Aug.10.</FONT></CENTER>

<CENTER>
<HR WIDTH="100%"></CENTER>

<CENTER><A HREF="../types.html">回到上一页</A></CENTER>

<CENTER>
<HR WIDTH="100%"></CENTER>

</BODY>
</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -