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.
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:
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.
Program structure and syntax:
Overview
Unit structure and syntax: Overview
Unit references and
the uses clause
Multiple and indirect
unit references
Multiple and indirect unit references
Unit references and the uses clause
单元之间彼此直接或间接引用时,称为互相依赖。只要单元之间不是全部通过接口节中的uses子句直接或间接造成循环,那么相互相依赖是允许的。换句话说,从一个单元的接口节开始,通过其他单元接口节uses子句的引用又回到该单元,这是决不可能的。(因为在这种情况下编译器将无法决定编译的顺序。)为了使相互依赖有效,每个循环引用路径中必需至少有一个uses子句出现在实现节。
最简单的情况是两个单元相互依赖,单元之间不能通过接口节中的uses子句彼此引用。因此,下面的例子将导致编译错误:
unit
Unit1;
interface
uses
Unit2;
...
unit
Unit2;
interface
uses
Unit1;
...
然而,可以将其中一个单元的引用移至实现节,使得互相依赖合法。例如:
unit
Unit1;
interface
uses
Unit2;
...
unit
Unit2;
interface
...
implementation
uses
Unit1;
...
为减少循环引用的机会,最好的方法是尽可能将单元列在在实现节的uses子句中。仅当要在接口节中使用另一单元中的标识符时(例如从其他的单元中继承类),才有必要将被使用的单元列入接口节uses子句中。
编者注
对于Borland提供的单元,一般列在开发者编写的单元的接口节中,如Forms、SysUtils等单元。此时不必担心循环依赖会发生,因为Borland提供的单元绝对不可能引用开发者编写的单元(开发者编写单元之前,Borland提供的单元就已经编写并编译完成了)。而对于开发者编写的单元,在引用时则需要尽量通过实现节中的uses子句来实现。因此,严格地说,Object Pascal不允许单元之间循环应用。