编辑“︁
Modula-3
”︁(章节)
跳转到导航
跳转到搜索
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
===过程=== ====过程类型==== 一个[[子程序|过程]]要么是<code>[[空指针|NIL]]</code>,要么是有如下构成的[[三元组]]: *过程体,它是一个语句。 *[[类型签名|签名]],它有如下形式<code>(formal_1; ...; formal_n): R RAISES S</code>,这里的每个<code>formal_i</code>是形式参数,<code>R</code>是结果类型,<code>S</code>是<code>RAISES</code>集合(这个过程可以引发的例外的集合)。 *环境,它是在解释过程体中变量名字方面有关的[[作用域]]。 形式参数有如下形式:{{code|2="objectpascal"|1=Mode Name: Type := Default}},这里的: *<code>Mode</code>是参数模态,它可以是<code>VALUE</code>、<code>VAR</code>或<code>READONLY</code>。如果省略了<code>Mode</code>,它缺省为<code>VALUE</code>。 *<code>Name</code>是命名这个形式参数的标识符。形式参数名字必须是各不相同的。 *<code>Type</code>是这个形式参数的类型。 *<code>Default</code>是一个常量表达式,它是这个形式参数的缺省值。如果<code>Mode</code>是<code>VAR</code>,则<code>:= Default</code>必须省略,否则<code>:= Default</code>和<code>: Type</code>中任何一个都可以省略,但不能二者都省略。如果省略了<code>Type</code>,它采用<code>Default</code>的类型。如果二者都存在,<code>Default</code>的值必须是<code>Type</code>的一个成员。 形式{{code|2="objectpascal"|1=Mode v_1, ..., v_n: Type := Default}},是{{code|2="objectpascal"|1=Mode v_1: Type := Default; ...; Mode v_n: Type := Default}}的简写。 <code>VAR</code>形式参数绑定到对应的实际参数所指示的变量上,也就是说它是别名。对于<code>VAR</code>形式参数,实际参数必须是可写的指定式,它的类型同于形式参数的类型,或者在<code>VAR</code>数组形式参数的情况下,它可赋值给这个形式参数。 <code>VALUE</code>形式参数绑定到具有未用的位置的一个变量上,并且它被初始化为实际参数对应的值。对于<code>VALUE</code>或<code>READONLY</code>形式参数,实际参数是可赋值给形式参数类型的任何表达式,并且放开了针对赋值局部过程的禁止。 <code>READONLY</code>形式参数,如果实际参数是指定式并且有与形式参数相同的类型,或者是可赋值给形式参数的类型的一个数组类型,则被当作<code>VAR</code>形式参数对待,它的只读语义体现在指定这个指定式为只读的,否则被当作<code>VALUE</code>形式参数对待。 在签名中,如果省略了<code>: R</code>,则这个过程是真正(proper)过程,否则为函数过程;如果省略了<code>RAISES S</code>,则假定它为<code>RAISES {}</code>。一个过程发起未包括在<code>RAISES</code>集合中的一个例外,是一个必查的运行时间错误,如果语言实现将这个运行时间错误映射成一个例外,则这个例外隐含的包括在所有的<code>RAISES</code>子句中。 ====过程声明==== 有两种形式的过程声明:只允许出现在接口中的{{code|2="modula2"|1=PROCEDURE id sig}},和只允许出现在模块中的{{code|2="modula2"|1=PROCEDURE id sig = B id}},这里的<code>id</code>是一个标识符,<code>sig</code>是过程[[类型签名|签名]],而<code>B</code>是一个块。在一个模块的最外层作用域内声明的过程是顶层过程,其他过程是局部过程。局部过程可以作为形式参数传递但不能被赋值,因为在栈实现下,局部过程在包含它的[[调用栈|栈桢]]被弹出后会成为无效的。 过程类型声明有如下形式:{{code|2="modula2"|1=TYPE T = PROCEDURE sig}},这里的<code>sig</code>是[[类型签名|签名]]规定。一个过程<code>P</code>是过程类型<code>T</code>的一个成员,或称为是它的一个值的条件为,它是<code>NIL</code>,或者它的签名被<code>T</code>的签名所含盖(cover)。这里的签名<code>sig_A</code>含盖签名<code>sig_B</code>的条件是: *它们有相同数目的形式参数,并且对应的形式参数有相同的类型和模态。 *它们有相同的结果类型,或者都没有结果类型。 *<code>sig_A</code>的<code>RAISES</code>集合包含<code>sig_B</code>的<code>RAISES</code>集合。 过程常量是声明为过程的一个标识符。过程变量是声明为具有过程类型的一个变量。例如: <syntaxhighlight lang="modula2"> PROCEDURE P(txt: TEXT := "P") = BEGIN IO.Put(txt) END P; VAR q: PROCEDURE(txt: TEXT := "Q") := P; </syntaxhighlight> 声明了过程常量<code>P</code>和过程变量<code>q</code>。两个过程如果有一致的[[闭包 (计算机科学)|闭包]],就是说它们涉及相同的过程体和环境,则二者相等即有相同的值。形式参数名字和缺省值,影响一个过程的类型即签名,而非这个过程的值。将一个过程常量赋值给一个过程变量,改变这个它的值,而非它的类型。比如上例中有:<code>P = q</code>为<code>TRUE</code>。缺省的形式参数的解释,由一个过程的类型来确定,而非这个过程的值。比如上例子中:<code>P()</code>打印<code>P</code>,而<code>q()</code>打印<code>Q</code>。 ====过程调用==== 过程调用有如下形式:<code>P(Bindings)</code>,这里的<code>P</code>是一个过程取值的表达式,而<code>Bindings</code>是关键字或位置绑定的一个列表。关键字绑定有如下形式:<code>name := actual</code>,这里的<code>actual</code>是一个表达式,而<code>name</code>是一个标识符。位置绑定有如下形式:<code>actual</code>,这里的<code>actual</code>是一个表达式。当关键字和位置绑定混合在一个调用中的时候,位置绑定必须前导于关键字绑定。如果绑定列表为空,圆括号仍然是需要的。 绑定列表要如下这样重写,来适合<code>P</code>的类型签名:首先,每个位置绑定<code>actual</code>,若为<code>Bindings</code>中的第<code>i</code>个绑定,则通过补充上第<code>i</code>个形式参数的名字,转换成关键字绑定增加到关键字绑定列表中。其次,对于有缺省值并且在第一步之后没有被绑定的每个形式参数,将它的形式参数的名字<code>name</code>和它的缺省值<code>default</code>,形成关键字绑定<code>name := default</code>增加到关键字绑定列表。重写成的关键字绑定列表必须只绑定形式参数,并且必须只绑定每个形式参数正好一次。 执行过程调用,需要求值过程取值表达式<code>P</code>和它的实际参数,绑定形式参数,并执行过程体。<code>P</code>和它的实际参数的求值次序是未定义的。调用一个未定义或<code>NIL</code>过程,是一个必查的运行时间错误。调用具有过程体<code>B</code>的真正过程,在绑定了实际参数之后等价于: <syntaxhighlight lang="objectpascal"> TRY B EXCEPT return-exception => (*skip*) END </syntaxhighlight>而调用具有过程体<code>B</code>的函数过程等价于: <syntaxhighlight lang="objectpascal"> TRY B; (错误:没有返回值) EXCEPT return-exception (v) => (结果成为v) END </syntaxhighlight>
摘要:
请注意,所有对Local Chinese Wikipedia的贡献均可能会被其他贡献者编辑、修改或删除。如果您不希望您的文字作品被随意编辑,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源(详情请见
Project:著作权
)。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
导航菜单
个人工具
未登录
讨论
贡献
创建账号
登录
命名空间
页面
讨论
大陆简体
不转换
简体
繁體
大陆简体
香港繁體
澳門繁體
大马简体
新加坡简体
臺灣正體
查看
阅读
编辑
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息