Кроме того,
Каждый блок состоит из двух отдельных частей. Интерфейс и реализация.
Раздел интерфейса содержит все общедоступные определения (типы, заголовки процедур, константы). Раздел реализации содержит все детали реализации.
При использовании устройства (с использованием предложения uses) вы получаете доступ к общедоступным определениям этого устройства. Этот доступ не является рекурсивным, поэтому, если интерфейс A A использует блок B, а блок C использует блок A, вы не получаете доступ к блоку B, если вы не используете его явно.
Раздел реализации имеет доступ к интерфейсу, к устройству, используемому в обоих случаях использования (интерфейс и реализация).
Интерфейсы используемых блоков скомпилированы перед тем, как продолжить компиляцию остальных. Это имеет то преимущество, что вы можете иметь круговой зависимости от в рамках реализации:
unit A;
interface
uses B;
unit B;
interface
implementation
uses A;
Который компилирует:
- попробовать интерфейс A, B неудачу нужно
- попробовать интерфейс B, хорошо!
- попробуйте интерфейс A, хорошо!
- попробуйте реализацию A, хорошо!
- попробуйте реализацию B, хорошо!
Каждый блок также имеет секцию инициализации (и если он имеет секцию инициализации, он также может иметь секцию финализации.) Секция инициализации используется для инициализации переменных единицы. Секции финализации используются для очистки. Когда вы используете их, разумно не рассчитывать на инициализацию других единиц. Просто держите их простыми и короткими.
Единицы также являются пространствами имен. Considder следующее:
unit A;
interface
const foo = 1;
unit B;
interface
const foo = 2;
unit C;
interface
uses A, B;
const
f1 = foo;
f2 = A.foo;
f3 = B.foo;
Если идентификатор определяется в нескольких используемых единицах, последний блок можно в списке изеза берется. Итак, f1 = 2. Но вы можете префикс его с именем (namespace) для решения этой проблемы.
С введением .net, мульти часть пространства имен разрешены, которая вводит другие приятные проблемы:
unit foo;
interface
type
rec1 = record
baz : Boolean;
end;
var
bar : rec1;
unit foo.bar;
interface
var
baz : Integer;
uses
foo, foo.bar;
begin
foo.bar.baz := true;
foo.bar.baz := 1;
end.
// 1. Which these lines gives an error and why?
// 2. Does the result change if you write uses foo.bar, foo?
В этом случае у вас есть конфликт. Но это разрешается, если присвоить именам имен более высокий приоритет. Таким образом, первая строка терпит неудачу.