воскресенье, 20 марта 2011 г.

Блоки и область видимости

Перевод из справочной системы Delphi

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



Блоки

Блок состоит из последовательности объявлений, за которым следует составная инструкция. Все объявления должны идти вместе, в начале блока. То есть блок имеет форму:

{declarations}
begin
  {statements}
end

Секция declarations может включать в себя объявления переменных, констант (включая resource strings), типов, процедур, функций и меток. В блоке программы могут также присутствовать один или несколько разделов exports (см. Libraries and Packages.)

Например, при объявлении функции:

function UpperCase(const S: string): string;
var
  Ch: Char;
  L: Integer;
  Source, Dest: PChar;
begin
   ...
end;

первая строка объявления – это заголовок функции и все последующие строки составляют блок. Ch, L, Source, и Dest – это локальные переменные, их объявления действительны только внутри блока функции UpperCase и в этом блоке они перекрывают любые объявления таких же идентификаторов, которые могут встретиться в блоке программы или секциях interface или implementation в модуле.


Область видимости

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

Правила, которые определяют область видимости идентификатора, могут быть сведены в таблицу:

Идентификатор объявлен в... Его область видимости ...
Секции объявлений программы, функции или процедуры Начинается от того места, где он объявлен и продолжается до конца текущего блока, включая все блоки, включенные в эту область видимости
Секции interface модуля Начинается от того, места, где он объявлен и продолжается до конца модуля, кроме того, он виден во всех модулях и программах, которые подключают этот модуль.
Секции implementation модуля, но вне блока какой либо процедуры или функции Начинается от того места, где он объявлен и заканчивается в конце модуля. Идентификатор также виден из любой функции или процедуры, объявленной в этом модуле, включая секции initialization и finalization (если таковые присутствуют).
Объявлении типа (запись). То есть идентификатор является именем поля в записи. Начинается от того места, где он объявлен и продолжается до конца объявления типа.
Объявлении класса (то есть идентификатор является именем свойства или метода класса) Начинается от того места, где он объявлен и продолжается до конца объявления класса. Кроме того, этот идентификатор будет виден всем классам-наследникам, а так же внутри блоков всех методов класса и его наследников.


Конфликты имен

Когда один блок включает в себя другой, они называются соответственно внешним и внутренним блоками. Если идентификатор объявлен во внешнем блоке и повторно объявлен во внутреннем блоке, объявление во внутреннем блоке имеет преимущество перед объявлением во внешнем и определяет смысл идентификатора на протяжении всего внутреннего блока. Например, если вы объявляете переменную MaxValue в секции interface модуля, и затем объявляете еще одну переменную с таким же именем внутри функции, объявленной в этом модуле, все неспецифицированные обращения к MaxValue внутри блока функции обрабатываются как второе, локальное объявление. Аналогично, функция, объявленная внутри другой функции создает новое внутреннее пространство имен, в которм идентификаторы, объявленные во внешней функции могут быть объявлены заново как локальные.

Использование нескольких модулей может усложнить определение области видимости. Каждый модуль, перечисленный в разделе подключения, создает новую область видимости, которая охватывает все модули, подключенные позже и непосредственно программу или модуль, содержащий рассматриваемый раздел подключения модулей. Первый модуль в разделе подключения представляет собой самую внешнюю область видимости, и каждый последующий модули представляет собой новую область видимости внутри предыдущей. Если два или более модуля объявляют одинаковые идентификаторы в своих секциях interface, то при неспецифицированном обращении к идентификатору выбирается самая внутренняя область видимости. То есть, выбирается тот модуль в котором непосредственно происходит обращение, или, если в этом модуле нет объявления идентификатора, выбирается модуль, последний подходящий модуль в разделе подключения модулей.
Модули System и SysInit подключаются автоматически ко всем программам и модулям. Объявления в модуле System, включая все предопределенные типы, подпрограммы и константы, которые компилятор понимает автоматически, всегда имеют более внешнюю область видимости.

Вы можете перекрыть эти правила и обойти внутреннее объявление, используя идентификатор со спецификатором или воспользовавшись инструкцией with.

Комментариев нет:

Отправить комментарий