Каков синтаксис объявления индексной переменной в блоке инициализации Delphi 2007 Pascal?

Мне нужно инициализировать и массив в блоке инициализации Delphi.

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

initialization
var
idx : Integer;
begin
    for idx := 0 to length(LastState)-1 do begin
        LastState[idx] := $FFFF;
    end;
end;

(Первая ошибка компиляции касается var):

([Ошибка DCC] ScheAutoInfRb2.pas (6898): ожидалось выражение E2029, но найден "VAR")

Это тоже не компилируется (потому что idx не объявлен):

initialization

    for idx := 0 to length(Last_Pro2State)-1 do begin
        Last_Pro2State[idx] := $FFFF;
    end;

[Ошибка DCC] ScheAutoInfRb2.pas (6899): Необъявленный идентификатор E2003: 'idx'

Я знаю, что могу объявить индексатор в объявлении основного модуля, но у этого есть несколько недостатков:

  1. Объявление индексатора отделено от его использования, но раздел реализации (который может находиться на расстоянии сотен строк) и

  2. В объем индексатора входят все функции и процедуры, описанные в разделе «Реализация».


person Jay Elston    schedule 22.02.2016    source источник
comment
Объявите процедуру, которая инициализирует массив непосредственно над разделом инициализации, и вызовите ее оттуда.   -  person Alex James    schedule 22.02.2016
comment
И объявите idx там же, где вы объявили LastState.   -  person Ed de Almeida    schedule 23.02.2016
comment
инициализация заменяет начало, а объявление переменной перед началом.   -  person Marco van de Voort    schedule 23.02.2016


Ответы (2)


Вы не можете.

Обычный способ сделать это - написать процедуру, которую вы затем вызываете из раздела initialization:

procedure InitLastStateArray;
var
  idx : Integer;
begin
  for idx := 0 to length(LastState)-1 do begin
    LastState[idx] := $FFFF;
  end;
end;

initialization
  IntLastStateArray;

end.
person Ken White    schedule 22.02.2016

Я знаю, что могу объявить индексатор в объявлении основного модуля, но у этого есть несколько недостатков:

Оба упомянутых вами недостатка можно избежать, объявив их в разделе implementation в самом конце, прямо над разделом initialization. Нет необходимости или пользы ни в том, чтобы размещать его в вашем разделе interface, ни в том, что он находится в верхней части раздела implementation: вы правы в отношении упомянутых вами недостатков, он излишне увеличивает область действия переменной и перемещает свое объявление от того места, где он используется, и нет никаких преимуществ, чтобы противостоять этому. Вам нужно только поместить переменные в раздел interface, если вы хотите, чтобы другие устройства имели доступ к этим переменным.

var
  idx : Integer;
initialization
  for idx := 0 to length(LastState)-1 do
    LastState[idx] := $FFFF;
end.

Это лучшее, что вы можете получить, в D7 нет возможности получить объявление переменной внутри блока initialization, но для полноты в более поздних версиях Delphi вы должны иметь возможность использовать анонимную процедуру, которая может быть определена полностью (включая локальные переменные ) внутри выражения практически где угодно.


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

person Community    schedule 22.02.2016
comment
Глобальная переменная - плохая идея. Поместите код в функцию. Здесь тоже нет причин для анонимных методов. - person David Heffernan; 22.02.2016
comment
@DavidHeffernan Меня не интересуют религиозные аргументы. Я знаю, когда глобальные переменные вызывают головную боль при обслуживании. Я избегаю их, когда они это делают. Я не избегаю их, когда они этого не делают. - person ; 22.02.2016
comment
Ошибка иметь переменную, срок жизни которой продлевает все время жизни программы, которая используется только при запуске. Я не верю, что это религия. - person David Heffernan; 22.02.2016
comment
@DavidHeffernan Нет, это не ошибка, это вопрос выбора меньшего зла. Это вопрос мнения, с которым мы не согласны. Это нормально. - person ; 22.02.2016
comment
В чем зло ограничения времени жизни переменных. Здесь нет ничего плохого в использовании процедуры. - person David Heffernan; 22.02.2016
comment
@DavidHeffernan Конечно, есть. Если очевидно, что код имеет смысл вызывать только один раз и извлекать его в отдельный метод, потребуется больше усилий, чтобы убедиться, что он вызывается только один раз и только из раздела инициализации. Да, это мелочь. То же самое и с глобальной переменной. - person ; 22.02.2016
comment
Переменная частной области видимости идеально подходит для этого случая. - person Free Consulting; 23.02.2016
comment
@FreeConsulting Возможно, вы упустили суть. initialization блоки не могут иметь частных переменных области видимости. - person ; 23.02.2016
comment
Переменные области модуля, которые используются только в разделе инициализации, обрабатываются компилятором как локальные переменные. Один из способов гарантировать, что переменная с единичной областью видимости используется только секцией инициализации, - это объявить ее непосредственно над этим разделом, и в этом случае это визуально похоже на объявление локальной переменной непосредственно над ключевым словом begin в обычная функция. (Когда есть также раздел финализации, становится труднее утверждать, что индексная переменная действительно локальная, поскольку она доступна для двух отдельных блоков.) - person Rob Kennedy; 23.02.2016
comment
@hvd, нет, там нет синтаксиса объявлений. На данный момент доступны два уровня области видимости, правильный один - это личная область действия юнита. - person Free Consulting; 23.02.2016
comment
@FreeConsulting Другими словами, что именно я вложил в свой ответ? - person ; 23.02.2016
comment
да. Поскольку OP, похоже, не понимает синтаксиса, я предлагаю вам добавить объяснение деклараций / операторов. - person Free Consulting; 23.02.2016
comment
@RobKennedy Спасибо за информацию, я не знал об этом. Оказывается, это не совсем так, но достаточно близко, я сделал примечание об этом. - person ; 23.02.2016