Понимание

Модули могут взаимно ссылаться друг на друга и зависеть друг от друга. Когда один модуль ссылается на другой, подключаемый модуль можно указать либо в секции 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. Такая двусторонняя циклическая структура полностью поддерживается компилятором.

Взаимные ссылки между модулями

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *