Delphi XE5教程7:单元引用和uses 子句
内容源自Delphi XE5 UPDATE 2官方帮助《Delphi Reference》,本人水平有限,欢迎各位高人修正相关错误!
也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者可QQ:34484690@qq.com
3 Unit References and the Uses Clause
3 单元引用和uses 子句
A uses clause lists units used by the program, library, or unit in which the clause appears. A uses clause can occur in
uses 子句列出了被程序、库或单元引用的单元(关于库,请参考库和包)。一个uses 子句可以出现在:
the project file for a program, or library
程序或库的工程文件
the interface section of a unit
单元的接口部分
the implementation section of a unit
单元的实现部分
Most project files contain a uses clause, as do the interface sections of most units. The implementation section of a unit can contain its own uses clause as well.
大多数工程文件包含一个uses 子句,大多数单元的接口部分也是如此,单元的实现部分也可以包含自己的uses 子句。
The System unit and the SysInit unit are used automatically by every application and cannot be listed explicitly in the uses clause. (System implements routines for file I/O, string handling, floating point operations, dynamic memory allocation, and so forth.) Other standard library units, such as SysUtils, must be explicitly included in the uses clause. In most cases, all necessary units are placed in the uses clause by the IDE, as you add and remove units from your project.
System 单元自动被每个程序所引用,并且不能在uses 子句中明确列出来(System 单元实现文件I/O、字符串处理、浮点运算、动态内存分配等例程)。其它一些标准单元,比如SysUtils,必须包含在uses 子句中。大多数情况下,当你在项目中添加和删除项目时,所有必需的单元将被IDE放在uses 子句中。
Case Sensitivity: In unit declarations and uses clauses, unit names must match the file names in case. In other contexts (such as qualified identifiers), unit names are case insensitive. To avoid problems with unit references, refer to the unit source file explicitly:
大小写敏感:在单元声明以及 uses 子句中(尤其是在Linux 下),单元名称必须和文件名大小写一致。在其它情况(比如使用限定符的标识符),单元名是大小写无关的。要避免在单元引用中出现问题,要明确指出单元文件:
uses MyUnit in "myunit.pas";
If such an explicit reference appears in the project file, other source files can refer to the unit with a simple uses clause that does not need to match case:
如果像上面这样在工程文件中明确引用一个单元,在其它源文件中就可以像下面那样简单地引用它,而不必考虑大小写问题:
uses Myunit;
1.1 The Syntax of a Uses Clause
3.1 uses 子句的语法
A uses clause consists of the reserved word uses, followed by one or more comma delimited unit names, followed by a semicolon. Examples:
一个 uses 子句由关键字uses、后面跟一个或多个由逗号隔开的单元名,最后是一个分号构成。举例如下:
uses Forms, Main; uses Forms, Main; uses Windows, Messages, SysUtils, Strings, Classes, Unit2, MyUnit;
In the uses clause of a program or library, any unit name may be followed by the reserved word in and the name of a source file, with or without a directory path, in single quotation marks; directory paths can be absolute or relative. Examples:
在程序或库(工程)的uses 子句中,任何单元名后面可以跟关键字in 和一个(单元)源文件名,源文件名用单引号括起来,可包括或不包括路径,路径可以是绝对路径,也可以是相对路径。举例如下:
uses Windows, Messages, SysUtils, Strings in 'C:\Classes\Strings.pas', Classes;
Use the keyword in after a unit name when you need to specify the unit's source file. Since the IDE expects unit names to match the names of the source files in which they reside, there is usually no reason to do this. Using in is necessary only when the location of the source file is unclear, for example when:
当要指定单元源文件时,在单元的名称后面包含in…。因为IDE 期望单元名和它所在的源文件名相同,所以通常没有理由这样做。只有当单元源文件的位置不明确时,你才需要使用in 关键字。比如,当
You have used a source file that is in a different directory from the project file, and that directory is not in the compiler's search path.
引用的单元文件和工程文件在不同的目录,并且单元所在的目录没有包含在编译器搜索路径、也不在库搜索路径中。
Different directories in the compiler's search path have identically named units.
编译器的不同搜索路径中有同名的单元。
You are compiling a console application from the command line, and you have named a unit with an identifier that doesn't match the name of its source file.
你在命令行编译一个控制台程序,并且单元名和它的文件名不同。
The compiler also relies on the in ... construction to determine which units are part of a project. Only units that appear in a project (.dpr) file's uses clause followed by in and a file name are considered to be part of the project; other units in the uses clause are used by the project without belonging to it. This distinction has no effect on compilation, but it affects IDE tools like the Project Manager.
编译器也根据 in…来判断哪些单元是工程的一部分。在工程文件(.dpr)的uses 子句中,只有后面包含in 和一个文件名的单元才被认为是工程的一部分,而其它单元只是被工程引用而不属于这个工程。这种区别对编译程序没有影响,但它影响IDE 工具,比如Project Manager 和Project Browser。
In the uses clause of a unit, you cannot use in to tell the compiler where to find a source file. Every unit must be in the compiler's search path. Moreover, unit names must match the names of their source files.
在单元的 uses 子句中,你不能用in 告诉编译器到哪里寻找单元文件。每个单元文件必须位于编译器搜索路径、或库搜索路径中,或者和引用它的单元文件位于同一路径;而且,单元名必须和它们的单元源文件同名。
1.2 Multiple and Indirect Unit References
3.2多重和间接单元引用
The order in which units appear in the uses clause determines the order of their initialization and affects the way identifiers are located by the compiler. If two units declare a variable, constant, type, procedure, or function with the same name, the compiler uses the one from the unit listed last in the uses clause. (To access the identifier from the other unit, you would have to add a qualifier: UnitName.Identifier.)
在 uses 子句中,单元出现的顺序决定了它们的初始化顺序(请参考初始化部分),也影响编译器对标识符的定位。如果两个单元声明了具有相同名称的变量、常量、类型、过程和函数,编译器使用uses子句中列在后面的那个单元所声明的标识符。若要访问其它单元的标识符,你必须添加限定符:UnitName.Identifier。
A uses clause need include only units used directly by the program or unit in which the clause appears. That is, if unit A references constants, types, variables, procedures, or functions that are declared in unit B, then A must use B explicitly. If B in turn references identifiers from unit C, then A is indirectly dependent on C; in this case, C needn't be included in a uses clause in A, but the compiler must still be able to find both B and C in order to process A.
在 uses 子句中,你只需列出被程序或单元直接引用的单元。也就是说,如果单元A 使用单元B 中声明的常量、变量、类型、过程或函数,则A 必须明确引用单元B;若单元B 引用单元C 的标志符,则单元A 是间接引用单元C。这种情况下,在单元A 的uses 子句中不必包含C,但编译器为了处理A,它还是必须能找到B 和C。
The following example illustrates indirect dependency:
下面的实例演示了间接引用:
program Prog; uses Unit2; const a = b; // ... unit Unit2; interface uses Unit1; const b = c; // ... unit Unit1; interface const c = 1; // ...
In this example, Prog depends directly on Unit2, which depends directly on Unit1. Hence Prog is indirectly dependent on Unit1. Because Unit1 does not appear in Prog's uses clause, identifiers declared in Unit1 are not available to Prog.
在这个例子中,Prog 直接引用单元Unit2,Unit2 又直接引用单元Unit1,因此,Prog 间接引用Unit1。因为Unit1 没出现在Prog 的uses 子句中,在Unit1 单元声明的标识符对Prog 是不可见的。
To compile a client module, the compiler needs to locate all units that the client depends on, directly or indirectly. Unless the source code for these units has changed, however, the compiler needs only their .dcu files, not their source (.pas) files.
要编译一个客户模块,编译器需要定位客户模块所引用的所有单元,不管是直接的还是间接的。但是,除非这些单元的源文件发生了改变,否则,编译器只需要它们的.dcu 文件,而不是它们的源文件(.pas)。
When a change is made in the interface section of a unit, other units that depend on the change must be recompiled. But when changes are made only in the implementation or other sections of a unit, dependent units don't have to be recompiled. The compiler tracks these dependencies automatically and recompiles units only when necessary.
当一个单元的接口部分被修改时,引用它的其它单元必须被重新编译;但若只修改了单元的实现部分或其它部分,引用它的单元没必要重新编译。编译器自动跟踪依赖关系,只有在需要时才重新编译单元。
1.3 Circular Unit References
3.3 循环单元引用
When units reference each other directly or indirectly, the units are said to be mutually dependent. Mutual dependencies are allowed as long as there are no circular paths connecting the uses clause of one interface section to the uses clause of another. In other words, starting from the interface section of a unit, it must never be possible to return to that unit by following references through interface sections of other units. For a pattern of mutual dependencies to be valid, each circular reference path must lead through the uses clause of at least one implementation section.
当单元间直接或间接地互相依赖(或引用)时,我们称这些单元为相互依赖。相互依赖是被允许的,只要在接口部分的uses 子句中不出现循环引用路径。换句话说,从一个单元的接口部分开始,沿着它所依赖的其它单元的接口部分的依赖路径,一定不能重新返回到这个单元。解决相互依赖问题的一种模式就是,每个循环引用必须至少有一个uses 子句出现在实现部分。
In the simplest case of two mutually dependent units, this means that the units cannot list each other in their interface uses clauses. So the following example leads to a compilation error:
在两个单元相互依赖这种最简单的情况下,你不能在它们的接口部分的uses 子句中互相列出对方。所以,下面的例子将产生编译错误:
unit Unit1; interface uses Unit2; // ... unit Unit2; interface uses Unit1; // ...
However, the two units can legally reference each other if one of the references is moved to the implementation section:
但是,若把其中的一个引用移到实现部分,这两个单元之间的相互引用将是合法的:
unit Unit1; interface uses Unit2; // ... unit Unit2; interface //... implementation uses Unit1; // ...
To reduce the chance of circular references, it's a good idea to list units in the implementation uses clause whenever possible. Only when identifiers from another unit are used in the interface section is it necessary to list that unit in the interface uses clause.
为了减少出现循环单元引用的机会,要尽可能在实现部分的uses 子句中引用单元。只有当来自另一个单元的标识符必须在接口部分使用时,才需要在接口部分的uses 子句中引用它。