Область действия идентификатора
Любой используемый в программе идентификатор должен быть предварительно описан. Идентификаторы описываются в разделе описаний. Идентификаторы для переменных могут также описываться внутри блока.
Основная программа, подпрограмма, блок, модуль, класс образуют так называемое пространство имен - область в программе, в которой имя должно иметь единственное описание. Таким образом, в одном пространстве имен не может быть описано двух одинаковых имен (исключение составляют перегруженные имена подпрограмм). Кроме того, в сборках .NET имеются явные определения пространств имен.
Область
действия идентификатора (т.е. место, где он может быть использован) простирается
от момента описания до конца блока, в котором он описан. Область действия глобального идентификатора, описанного в модуле, простирается на весь модуль,
а также на основную программу, к которой данный модуль подключен в разделе
uses
.
Кроме этого, имеются переменные, определенные в блоке и связанные с некоторыми
конструкциями (for
, foreach
). В этом
случае действие переменной i
простирается до конца соответствующей
конструкции. Так, следующий код корректен:
var a: array of integer := (3,5,7); for i: integer := 1 to 9 do
write(a[i]);
foreach i: integer in a do
write(i);
Идентификатор с тем же именем, определенный во вложенном пространстве имен, скрывает идентификатор, определенный во внешнем пространстве имен. Например, в коде
var i: integer;
procedure p;
var i: integer;
begin
i := 5;
end;
значение 5 будет присвоено переменной i
, описанной в процедуре
p
; внутри же процедуры p
сослаться на глобальную переменную i
невозможно.
Переменные, описанные внутри блока, не могут иметь те же имена, что и переменные из раздела описаний этого блока. Например, следующая программа ошибочна:
var i: integer;
begin
var i: integer; // ошибка
end.
В производных классах, напротив, можно определять члены с теми же именами, что и в базовых классах, при
этом их имена скрывают соответствующие имена в базовых классах.
Для обращения к одноименному члену базового класса из метода производного класса используется
ключевое слово
inherited
:
type
A=class
i: integer;
procedure p;
begin
i := 5;
end;
end;
B=class(A)
i: integer;
procedure p;
begin
i := 5;
inherited p;
end;
end;
Алгоритм поиска имени в классе следующий: вначале имя ищется в текущем классе, затем в его базовых классах, а если не найдено, то в глобальной области видимости.
Алгоритм поиска имени в глобальной области видимости при наличии нескольких подключенных модулей следующий: вначале имя ищется в текущем модуле, затем, если не найдено, по цепочке подключенных модулей в порядке справа налево. Например, в программе
uses unit1,unit2;
begin
id := 2;
end.
описание переменной id
будет искаться вначале в основной
программе, затем в модуле unit2
, затем в модуле unit1
.
При этом в разных модулях могут быть описаны разные переменные id
.
Данная ситуация означает, что unit1
образует внешнее пространство
имен, пространство имен unit2
в него непосредственно вложено, а
пространство имен основной программы вложено в unit2
.
Если в последнем примере оба модуля - unit1
и unit2
- определяют переменные id
, то рекомендуется уточнять имя
переменной именем модуля, используя конструкцию
ИмяМодуля.
Имя:
uses unit1,unit2;
begin
unit1.id := 2;
end.