Nil/ru
│
Deutsch (de) │
English (en) │
suomi (fi) │
français (fr) │
русский (ru) │
中文(中国大陆) (zh_CN) │
Зарезервированное слово nil
представляет собой специальное значение переменной-указателя, не указывающей ни на что конкретное. В FPC это реализовано как pointer(0)
(числовое значение 0
), однако программист не должен использовать этот факт. На других языках программирования, например на C, кто-то пишет null
. Термины “null pointer” или “nil pointer” используются взаимозаменяемо, даже среди программистов на Паскале.
Есть два популярных объяснения этимологии nil
. Кто-то говорит: nil
означает латинское слово «nihil», означающее «ничего». Другой предполагает, что NIL
- это английская аббревиатура, обозначающая “not in list” (нет в списке). Может быть, поскольку немецкое слово «Null» обозначает цифру «ноль», чтобы избежать путаницы или для различия между понятием и значением, было выбрано слово nil
. Во всяком случае, это не имеет никакой разницы при программировании.
Совместимость присвоения
nil
can be of course assigned to a pointer
variable, but also to other types, which are in fact pointers, but their usage is more convenient.
For instance dynamic arrays or classes:
Конечно, nil
может быть присвоен переменной pointer
, но также и другим типам, которые на самом деле являются указателями, но их использование более удобно. Например, динамические массивы или классы:
program nilDemo(input, output, stderr);
var
loc: pointer;
chk: array of boolean;
msg: PChar;
prc: TProcedure;
obj: TObject;
begin
// указываем в никуда
loc := nil;
// очищаем динамический массив
chk := nil;
// очищаем строку
msg := nil;
// процедурная переменная не ссылается ни на одну процедуру
prc := nil;
// теряем ссылку на объект
obj := nil;
end.
Обратите внимание, что присвоение nil
динамическому массиву практически эквивалентно вызову процедуры setLength(dynamicArrayVariable, 0)
. Значения массива теряются, если счетчик ссылок dynamicArrayVariable достигает нуля. Однако не существует сопоставимого механизма для других типов, например, присвоение nil
переменной class
'а или pointer
не освободит (т.е. де-аллокирует) память, которая, возможно, была занята ссылочной структурой.
Приложение
В манере Паскаля вы обычно не пишете такие выражения, как pointerVariable = nil
, а используете более толковые идентификаторы. Шаблон system.assigned
заменяется точно таким же выражением, но скрывает тот факт, что переменная (реализована как) указатель. Поэтому его использование не является обязательным.
Шаблон SysUtils.FreeAndNil
будет вызывать шаблон класса free
и присваивать nil
передаваемому указателю (переменной типа class). Хотя это хорошая идея, очистить указатели, которые больше не указывают на допустимые объекты, это может усложнить отладку, так как нет доступного указателя, указывающего на адрес, которым был определенный объект.
См.также
- Оператор разыменования указателя
^
- Переменная
system.returnNilIfGrowHeapFails
{$objectChecks on}
- Обнуляемые типы