Compreensão
As unidades podem depender e se referenciar mutuamente. Quando uma unidade referencia outra, a unidade referenciada pode ser declarada na seção interface ou apenas na seção implementation. As diferenças entre os dois modos estão descritas abaixo:
Declarado em interface (referência na seção de interface): É possível definir novos elementos públicos (procedimentos, tipos personalizados etc.) visíveis externamente com base no conteúdo da unidade referenciada, acessíveis por todas as outras unidades do projeto.
Declarado apenas em implementation (referência na seção de implementação): O escopo de uso é limitado. Os identificadores da unidade referenciada só podem ser utilizados no código de implementação da unidade atual e não são acessíveis externamente.
Exemplo
O trecho abaixo é apenas uma demonstração. O leitor ainda não estudou classes, basta entender o conceito por enquanto.
Crie um novo arquivo de unidade 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.
Depois faça a referência dessa unidade dentro de AnotherUnit.pas
unit AnotherUnit;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
interface
uses
Classes;
// A classe TComponent está definida na unidade Classes, então é necessário referenciar Classes na seção interface
procedure DoSomethingWithComponent(var C: TComponent);
implementation
uses SysUtils; // SysUtils referenciado somente na seção implementation
procedure DoSomethingWithComponent(var C: TComponent);
begin
// FreeAndNil vem de SysUtils e só é chamado no código de implementação; basta declarar a referência em implementation
FreeAndNil(C);
end;
end.Code language: JavaScript (javascript)
Observações
1 Dependências circulares bidirecionais são proibidas na seção interface
Não é permitido que duas unidades se referenciem mutuamente nas suas respectivas seções interface ao mesmo tempo.
Princípio: Ao analisar a interface de uma unidade, o compilador precisa resolver completamente todas as unidades dependentes listadas na cláusula uses da seção interface dessa unidade. O Pascal segue essa regra rigorosamente e traz dois grandes benefícios:
Compilação mais rápida; o compilador identifica automaticamente quais unidades precisam ser recompiladas sem manutenção manual de scripts Makefile complexos. Após alterar o código, não é preciso recompilar todo o projeto para garantir a atualização sincronizada de todas as dependências.
2 Dependências circulares são permitidas na seção implementation
Uma dependência circular é válida se pelo menos um dos lados referenciar a outra unidade apenas na seção implementation.
Exemplo: A unidade A referencia a unidade B na seção interface, enquanto a unidade B referencia a unidade A somente na seção implementation. Essa estrutura circular bidirecional é totalmente suportada pelo compilador.