虚拟全书 > 核心语言 > 模块化和事物的命名 > 模块工作方式 >

模块工作方式

Mathematica 中模块的基本工作方式非常简单. 任何模块每一次使用时,就产生一个新符号去代表它的每一个局部变量. 新符号的名字被唯一地给定,它不能跟任何其它名字冲突. 命名的方法是在给定的局部变量后加 ,并给出唯一的序号.
从全局变量 $ModuleNumber 的值可以找到序列号. 该变量计算 Module 的任何形式所使用的总次数.
Module 中产生形如 x$nnn 的符号去代表每个局部变量.

Mathematica 中模块的基本原理.

这里说明了模块内所产生 的符号.
任何模块每一次运行时产生的符号不同.
在绝大部分情况下,不需要直接涉及模块内产生的实际符号. 但在一个模块的执行过程中打开对话时就会看到这些符号. 同样,用函数如 Trace 等也能观察模块的计算.
Trace 观察模块内部产生的符号.
In[3]:=
Click for copyable input
Out[3]=
在模块中打开对话.
In[4]:=
Click for copyable input
在对话内看到为 等局部变量产生的符号.
In[5]:=
Click for copyable input
Out[5]=
可以像其它符号一样来处理这些符号.
In[6]:=
Click for copyable input
Out[6]=
从对话返回.
In[7]:=
Click for copyable input
Out[7]=
在某些情况下,明确返回在模块中产生的符号是很方便的.
可以明确地返回在模块中产生的符号.
In[8]:=
Click for copyable input
Out[8]=
可以把这些符号像其它符号一样处理.
In[9]:=
Click for copyable input
Out[9]=
Unique[x]产生形如 唯一名称的新符号
Unique[{x,y,...}]产生一个新符号表

通过唯一的名称产生新符号.

函数 UniqueModule 一样产生新符号. 每次调用 Unique 时,$ModuleNumber 增加,故可保证新符号的名称不重复.
产生唯一的名称以 开头的新符号.
In[10]:=
Click for copyable input
Out[10]=
每调用一次 Unique 就得到一个序列号更大的符号.
In[11]:=
Click for copyable input
Out[11]=
对一个集合调用 Unique 时,得到每个符号有相同的序列号.
In[12]:=
Click for copyable input
Out[12]=
可以用标准 Mathematica ?name 机制得到在模块中或用函数 Unique 产生符号的信息.
执行这一模块产生符号 .
In[13]:=
Click for copyable input
Out[13]=
这里可以看到所产生的符号.
模块 Module 所产生的符号与计算中的符号性能相同. 但这些符号具有 Temporary 属性,当不再使用时它们会被系统删除,所以在模块内产生的符号当模块执行完时就被删除. 那些明确返回的符号才能继续存在.
这里显示了在模块内产生的新变量 .
这个新变量在模块执行结束时被删除,所以这里不再出现.
应该意识到对所产生的符号用 等符号名完全是一种约定. 一般地,可以对任何符号用这类符号,但这样做时可能会与模式 Module 所产生的符号重合.
重要的一点是由模式 Module 所产生的符号的唯一性仅仅在 Mathematica 的一个进程中是唯一的. 决定符合序列数的变量 $ModuleNumber 在每个进程的开始时总是重新设置.
这意味着将含有所产生符号的表达式存在一个文件中,然后在另一个进程中打开该文件时无法保证不冲突.
避免这种冲突的一个途径是在每个进程的开始时直接设置不同的 $ModuleNumber,特别,当设置$ModuleNumber=10^10 $SessionID 时就可以避免任何冲突. 全局变量 $SessionID 给出刻划特定Mathematica 进程的唯一数. 这个变量的值由日期和时间、所用计算的ID、以及特定 Mathematica 过程的ID等决定.
$ModuleNumberModuleUnique 所产生符号的序列号
$SessionID在每个 Mathematica 进程中都不重复的数

决定所产生符号序列号的变量.

在产生了决定局部变量的符号后,Module 就用这些符号计算 body. 首先取模块中出现的 body 的实际表达式,用 With 将每个局部变量的名称用所产生的符号代替,然后模块 Module 来计算结果中表达式的值.
重要的是 Module 仅将所产生的符号代入 body 的实际表达式中. 但它不把这些符号代入 body 所调用的但不直接出现在 body 中的代码中.
"块和局部值" 节将讨论如何用 Block 去建立以不同方式工作的"局部值".
由于 没有直接出现在模块的body中,故没有它的局部值.
In[17]:=
Click for copyable input
Out[17]=
大部分情况下,通过 Module 的直接输入来在 Mathematica 中建立模块. 由于 Module 函数具有属性HoldAll,所以在模块执行之前 body 将维持不计算的状态.
Mathematica 中还可以建立动态模块. 新符号的产生以及向 body 中的代入总是在模块执行时进行,而不是在模块作为 Mathematica 输入建立时进行.
这里立即计算模块的内部,直接给出 的值.
In[18]:=
Click for copyable input
Out[18]=
Ask a question about this page  |  Suggest an improvement  |  Leave a message for the team
格式:   HTML  |  CDF