Кроме того,
Каждая единица состоит из двух отдельных частей. Интерфейс и реализация.
Раздел интерфейса содержит все общедоступные определения (типы, заголовки процедур, константы). Раздел реализации содержит все детали реализации.
Когда вы используете модуль (используя предложение uses), вы получаете доступ к общедоступным определениям этого модуля. Этот доступ не является рекурсивным, поэтому, если интерфейс модуля A использует модуль B, а модуль C использует модуль A, вы не получите доступ к модулю B, если не используете его явно.
Секция реализации имеет доступ к интерфейсу, к единице, используемой в обоих разделах использования (интерфейс и реализация).
Сначала компилируются интерфейсы используемых модулей, а потом компилируются остальные. Это имеет то преимущество, что вы можете иметь циклические зависимости внутри реализации:
unit A;
interface
uses B;
unit B;
interface
implementation
uses A;
Что компилируется:
- попробуйте интерфейс A, не нужен B
- попробуйте интерфейс B, хорошо!
- попробуйте интерфейс A, хорошо!
- попробуйте реализацию А, хорошо!
- попробуйте реализацию B, хорошо!
Каждый модуль также имеет раздел инициализации (а если он имеет раздел инициализации, он также может иметь раздел финализации). Раздел инициализации используется для инициализации переменных модуля. Разделы финализации используются для очистки. Когда вы используете их, разумно не рассчитывать на инициализацию других модулей. Просто держите их простыми и короткими.
Модуль также является пространством имен. Учтите следующее:
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. Но вы можете добавить к нему префикс имени модуля (пространства имен), чтобы решить эту проблему.
С введением .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?
В этом случае у вас конфликт. Но это решается путем присвоения именам пространств имен более высокого приоритета. Итак, первая строка не работает.
person
Toon Krijthe
schedule
06.04.2009