Добавление модуля в интерфейс использует предложение, а не использование реализации использует

При использовании Delphi: если у меня есть модуль, который заполнен константами, такими как...

Unit AConsts;
Interface
Const
     Const1 : WideString = 'Const1';
     Const2 : WideString = 'Const2';
     Const3 : WideString = 'Const3';
     Const4 = 100;
     Const5 = 100;
Implementation
end.

и я хочу использовать этот блок из другого блока, есть ли разница между...

Unit AUnit;
Interface
Uses 
    AConsts;
Implementation
end.

а также

Unit AUnit;
Interface
Implementation
Uses
    AConsts;
end.

? Или, другими словами, есть ли разница между ними в том, что касается скомпилированного приложения?

[Редактировать 1]

Спасибо за ответы до сих пор.

Я не достаточно ясно дал понять этот вопрос, и за это прошу прощения. Вопрос не в области действия, избегании циклических ссылок и т. Д. Речь идет о различиях в скомпилированном приложении. Может быть, другой пример поможет.

Если UnitA, UnitB и UnitC все используют AConsts, будет ли разница в скомпилированном приложении (при условии отсутствия конфликта имен между константами в модулях AConsts и другом коде) между App1, где все эти UnitA, UnitB и UnitC имеют ACons в интерфейсе раздел использует раздел и App2, где UnitA, UnitB и UnitC имеют ACons в разделе использования раздела Реализация.

5 ответов

Решение

Разница заключается в том, где вам разрешено ссылаться на то, что AConsts имеет в своем разделе интерфейса. Во-первых AUnitВы могли бы использовать Const4 объявить массив фиксированного размера в этом разделе интерфейса. Вы не могли сделать это во втором AUnit так как Const4 не в сфере.

Это может повлиять на скомпилированную программу, если вы не будете осторожны. Предположим, у нас есть другой модуль, который также объявляет константу с именем Const4:

unit BConsts;
interface
const
  Const4 = 50;
implementation
end.

Теперь мы определяем массив в UnitA как это:

unit AUnit
interface
uses BConsts;
var
  data: array[0..Pred(Const4)] of Integer;
implementation
uses AConsts;
procedure Work;
var
  i: Integer;
begin
  for i := 0 to Const4 - 1 do begin
    data[i] := 8;
  end;
end;
end.

Этот код будет записываться после конца массива, потому что Const4 это по объему в разделе интерфейса не то же самое Const4 это используется в разделе реализации. Это не часто случается с константами. Обычно это происходит только с двумя идентификаторами, FindClose функция, определенная в Windows а также SysUtils, а также TBitmap, определенный в Graphics а также Windows, И в этих двух случаях компилятор скажет вам, что вы сделали что-то не так, хотя он не скажет вам точно, что вы использовали идентификатор, который имеет два разных значения. Вы можете решить проблему, указав идентификатор:

for i := 0 to BConsts.Const4 - 1 do
  data[i] := 8;

Если все вышеперечисленные меры предосторожности учтены, и ваша программа компилируется и работает правильно, то не имеет значения, где используются модули. В вашем примере с App1 и App2 две программы будут одинаковыми. Они не будут идентичны - компилятор будет обрабатывать вещи в другом порядке и, таким образом, вероятно, будет размещать вещи в разных местах - но это не повлияет на выполнение вашей программы.

Я помещаю все ссылки в раздел реализации и помещаю только те имена модулей в интерфейс, который мне нужен.

Однако я хотел бы максимально ограничить охват всего, и эта политика соответствует этому.

В среде IDE также используется способ декларирования использования, чтобы определить, что нужно для компиляции.

Если ваша секция интерфейса использует UnitA, а ваша секция реализации использует UnitB, то, если блок B нуждается в перекомпиляции, ваш блок не будет, но если unitA изменится, то ваш блок нужно будет перекомпилировать.

Это один из секретов супер быстрой скорости сборки Delphis.

Что касается вашего готового исполняемого файла, я ожидаю, что он будет иметь одинаковый размер, куда бы вы ни поместили объявления (компоновщик умен и содержит только ссылки в методах и т. Д., Которые фактически используются вашим приложением), но фактическое расположение различных источников почти конечно, изменится, если изменится порядок объявлений единиц.

Элементы в выражении использования в интерфейсе видны во всем модуле.

Элементы в выражении использования в реализации видны только в разделе реализации.

Пример:

unit A;
interface
const 
  cA = 1;
..


unit B;
interface
const 
  cB = 1;
..



unit C;
interface
uses
  A;
const 
  cC1 = cA;
  cC2 = cB; // Error

implementation
uses
  B;
const
  cC3 = cA;
  cC4 = cB;

end.

Вы можете создать взаимозависимые блоки, если хотя бы один из них включен в раздел реализации:

unit A;
interface
implementation
uses
  B;
end.


unit B;
interface
implementation
uses
  A;
end.

Если оба используются в разделе интерфейса, он не будет компилироваться / связываться.

Я следую правилу, согласно которому я помещаю все в интерфейсную часть, если мне не нужно решать проблемы с циклическими ссылками. Это помогает внести немного ясности. Некоторые мастера в Delphi и диалоге "Файл> Использовать модуль..." помещают модули в раздел реализации.

За исключением обзорных ловушек, которые выделил Роб Кеннеди, это не имеет значения. Сделайте свой стандарт и придерживайтесь его.

Другие вопросы по тегам