Ответ 1
Это хорошо документировано в записях perldoc для defined
и exists
. Вот краткое резюме:
defined $hash{key}
указывает, определено ли значение для данного ключа (т.е. не undef
). Используйте его для различения значений undefined и значений, которые являются ложными в булевом контексте, таких как 0
и ''
.
exists $hash{key}
указывает, содержит или нет %hash
данный ключ. Используйте его, чтобы различать значения undefined и несуществующие.
Это проще всего увидеть на примере. Учитывая этот хеш:
my %hash = (a => 1, b => 0, c => undef);
Вот результаты поиска, определения и существования:
# key value defined exists
a 1 1 1
b 0 1 1
c undef 0 1
d undef 0 0
На практике люди часто пишут только if ($hash{key}) {...}
, потому что (во многих распространенных случаях) только истинные значения являются значимыми/возможными. Если значения false действительны, вы должны добавить defined()
к тесту. exists()
используется гораздо реже. Наиболее распространенный случай, вероятно, при использовании хэша в качестве набора. например.
my %set = map { $_ => undef } 'a' .. 'z';
Использование undef
для заданных значений имеет несколько преимуществ:
- Это более точно представляет намерение (только клавиши имеют смысл, а не значения).
- Все значения
undef
разделяют одно выделение (которое сохраняет память). -
exists()
тесты немного быстрее (потому что Perl не нужно извлекать значение, а только определить, что он есть).
У него также есть недостаток, что вы должны использовать exists()
для проверки членства в наборе, что требует большего набора текста и сделает неправильную вещь, если вы забудете его.
Другое место, где exists
полезно, - это исследовать заблокированные хэши, прежде чем пытаться извлечь значение (которое вызовет исключение).