Понимание
Модули могут взаимно ссылаться друг на друга и зависеть друг от друга. Когда один модуль ссылается на другой, подключаемый модуль можно указать либо в секции interface (интерфейс), либо исключительно в секции implementation (реализация). Различия этих двух подходов описаны ниже:
Указание в секции interface (ссылка через интерфейс): На основе содержимого подключаемого модуля можно объявить новые общедоступные элементы (процедуры, пользовательские типы и т.д.), доступные для всех остальных модулей всего проекта.
Указание только в секции implementation (ссылка через реализацию): Область видимости ограничена. Идентификаторы из подключаемого модуля можно использовать только внутри кода реализации текущего модуля, извне они недоступны.
Пример
Приведённый код является демонстрационным. Читатель ещё не изучал классы, поэтому достаточно усвоить лишь основную концепцию.
Создайте новый файл модуля Classes.pas
unit Classes;
{$mode objfpc}{$H+}
interface
type
TObject=class;
TComponent=class(TObject)
constructor Create(AOwner:TComponent);virtual;
end;
TObject=class
destructor Destroy;virtual;
end;
implementation
constructor TComponent.Create(AOwner:TComponent);begin end;
destructor TObject.Destroy;begin end;
end.
Далее подключите этот модуль в файле AnotherUnit.pas
unit AnotherUnit;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
interface
uses
Classes;
// Класс TComponent определён в модуле Classes, поэтому модуль Classes нужно подключать в секции interface
procedure DoSomethingWithComponent(var C: TComponent);
implementation
uses SysUtils; // SysUtils подключается только в секции реализации
procedure DoSomethingWithComponent(var C: TComponent);
begin
// Процедура FreeAndNil из модуля SysUtils вызывается только в коде реализации, достаточно подключить SysUtils в implementation
FreeAndNil(C);
end;
end.Code language: JavaScript (javascript)
Примечания
1 В секции interface запрещены двусторонние циклические зависимости
Запрещено, чтобы два модуля одновременно ссылались друг на друга в своих секциях interface.
Принцип: При разборе интерфейса модуля компилятор должен полностью обработать все зависимые модули, перечисленные в предложении uses секции interface этого модуля. Pascal строго соблюдает данное правило, что даёт два важных преимущества:
Ускорение компиляции; компилятор автоматически определяет, какие модули нужно перекомпилировать, без ручного сопровождения сложных скриптов сборки Makefile. После редактирования кода не требуется перекомпилировать весь проект, при этом гарантируется синхронное обновление всех зависимостей.
2 В секции implementation циклические зависимости допустимы
Циклическая зависимость является корректной, если хотя бы один из модулей ссылается на второй исключительно в секции implementation.
Пример: Модуль A ссылается на модуль B в секции interface, а модуль B ссылается на модуль A только в секции implementation. Такая двусторонняя циклическая структура полностью поддерживается компилятором.
Взаимные ссылки между модулями