Добавление модуля в интерфейс использует предложение, а не использование реализации - PullRequest
6 голосов
/ 09 февраля 2009

При использовании 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 ]

10 голосов
/ 09 февраля 2009

Разница заключается в том, где вам разрешено ссылаться на то, что 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 две программы будут одинаковыми. Они не будут идентичны - компилятор будет обрабатывать вещи в другом порядке и, таким образом, вероятно, будет размещать вещи в разных местах - но это не повлияет на выполнение вашей программы.

3 голосов
/ 10 февраля 2009

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

Мне нравится, насколько это возможно, ограничивать сферу всего, и эта политика соответствует этому.

2 голосов
/ 09 февраля 2009

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

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

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

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

1 голос
/ 09 февраля 2009

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

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

1 голос
/ 09 февраля 2009

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

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

Пример:

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.

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

...