Grundlagen verstehen
Einheiten können sich gegenseitig referenzieren und voneinander abhängen. Wenn eine Einheit eine andere referenziert, kann die referenzierte Einheit entweder im Abschnitt interface oder ausschließlich im Abschnitt implementation angegeben werden. Die Unterschiede der beiden Varianten sind im Folgenden aufgeführt:
Eintrag im interface-Bereich (Referenz über Schnittstelle): Auf Basis des Inhalts der referenzierten Einheit lassen sich neue öffentliche Elemente (Prozeduren, benutzerdefinierte Typen usw.) nach außen definieren, die von allen anderen Einheiten im gesamten Projekt aufgerufen werden können.
Nur im implementation-Bereich eingetragen (Referenz über Implementierung): Der Gültigkeitsbereich ist eingeschränkt. Bezeichner aus der referenzierten Einheit dürfen nur innerhalb des Implementierungscodes der aktuellen Einheit verwendet werden und sind von außen nicht zugänglich.
Beispiel
Der folgende Code dient nur zur Demonstration. Der Leser hat Klassen noch nicht gelernt, es reicht daher, zunächst nur das Konzept zu erfassen.
Erstellen Sie eine neue Einheitsdatei 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.
Anschließend referenzieren Sie diese Einheit in AnotherUnit.pas
unit AnotherUnit;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
interface
uses
Classes;
// Die Klasse TComponent ist in der Einheit Classes definiert, daher muss Classes im interface-Bereich referenziert werden
procedure DoSomethingWithComponent(var C: TComponent);
implementation
uses SysUtils; // SysUtils nur im Implementierungsbereich referenziert
procedure DoSomethingWithComponent(var C: TComponent);
begin
// FreeAndNil stammt aus SysUtils und wird nur im Implementierungscode aufgerufen; eine Referenz im implementation-Bereich reicht vollständig aus
FreeAndNil(C);
end;
end.Code-Sprache: JavaScript (javascript)
Hinweise
1 Bidirektionale zyklische Abhängigkeiten im interface-Bereich verboten
Es ist nicht zulässig, dass zwei Einheiten sich gleichzeitig gegenseitig in ihren jeweiligen interface-Abschnitten referenzieren.
Grundlage: Beim Auswerten der Schnittstelle einer Einheit muss der Compiler alle abhängigen Einheiten vollständig auflösen, die in der uses-Klausel des interface-Bereichs aufgeführt sind. Pascal hält sich streng an diese Regel, was zwei große Vorteile mit sich bringt:
Schnellere Kompilierung; der Compiler erkennt automatisch, welche Einheiten neu kompiliert werden müssen, ohne dass komplexe Makefile-Build-Skripte manuell verwaltet werden. Nach Codeänderungen muss nicht das gesamte Projekt neu übersetzt werden, dennoch werden alle Abhängigkeiten synchron aktualisiert.
2 Zyklische Abhängigkeiten im implementation-Bereich erlaubt
Eine zyklische Abhängigkeit ist zulässig, solange mindestens eine Seite die gegenseitige Einheit ausschließlich im implementation-Bereich referenziert.
Beispiel: Einheit A referenziert Einheit B im interface-Bereich, Einheit B referenziert Einheit A nur im implementation-Bereich. Diese bidirektionale zyklische Struktur wird vom Compiler uneingeschränkt unterstützt.