Различия и использование If Assigned(Foo) и If (Foo <> nil) в Delphi
В языке программирования Delphi, когда речь заходит о проверке на ноль (NULL) для указателей, часто возникает вопрос о том, как правильно это делать: через функцию Assigned() или через обычный оператор сравнения <> nil. Давайте разберемся, в чем заключаются эти различия и когда следует использовать каждую из этих конструкций.
Официальная документация
Согласно официальной документации, функция Assigned(P) эквивалентна тесту P <> nil для указательных переменных и @P <> nil для переменных с процедурами. Таким образом, для не процедурных указателей (например, переменных типов PInteger, PMyRec, TBitmap, TList<integer>, или TFormClass) Assigned(P) идентичен P <> nil.
Примеры использования
var
i: Integer;
p: PInteger;
begin
i := 5;
p := @i;
if Assigned(p) then // True
p := nil;
if Assigned(p) then // False
end;
L := TList<Integer>.Create;
try
if Assigned(L) then // True
// Используем список L
finally
L.Free;
end;
if Assigned(L) then // False
// Список уже освобожден, использовать нельзя
Особенности для переменных с процедурами
Для переменных с процедурами Assigned(P) эквивалентен @P <> nil, в то время как P <> nil попытается выполнить процедуру или функцию, на которую указывает P, с пустым списком параметров. Это может привести к ошибке компиляции, так как процедура не возвращает значение, которое можно было бы сравнить с nil.
type
TStringProc = procedure(const AText: string);
TGetPtrFunc = function: pointer;
procedure MyStrProc(const AText: string);
begin
ShowMessage(AText);
end;
var
SP: TStringProc;
begin
SP := MyStrProc;
if Assigned(SP) then // True
SP('test'); // Вызов процедуры
SP := nil;
if Assigned(SP) then // False
// Попытка вызова процедуры приведет к ошибке
if @SP <> nil then // False
// Правильный способ проверки
end;
Заключение
Использование Assigned(X) или X <> nil для указателей, не являющихся процедурными, — это вопрос стиля. Лично я предпочитаю использовать Assigned(X), когда нужно проверить, что переменная не nil, и X = nil (или @X = nil), когда нужно проверить, что переменная не содержит ссылку на действительные объекты до того, как была инициализирована, так как not Assigned(X) может быть менее компактным.
Важное замечание: Обе конструкции лишь проверяют, равно ли значение указателя nil, и не гарантируют, что указатель указывает на действительные или корректные данные. Если указатель не был инициализирован, он может указывать на мусорные данные.
Итак, в зависимости от типа переменной (указатель или процедура) и от предпочтений разработчика, можно использовать как Assigned(Foo), так и Foo <> nil для проверки на ноль в Delphi.
Отличие и применение `If Assigned(Foo)` и `If (Foo <> nil)` в Delphi заключается в том, что `Assigned()` предназначен для безопасной проверки указателей, включая переменные с процедурами, тогда как `Foo <> nil` напрямую сравнивает указатель с `nil` и мож
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.