Это хорошо задокументировано в записях perldoc для defined
и exists
.Вот краткая сводка:
defined $hash{key}
сообщает вам, определено ли значение для данного ключа (т. Е. Не undef
).Используйте его, чтобы различать неопределенные значения и значения, которые являются ложными в логическом контексте, таком как 0
и ''
.
exists $hash{key}
говорит вам, содержит ли %hash
данный ключ.Используйте его, чтобы различать неопределенные значения и несуществующие.
Это проще всего увидеть на примере.С учетом этого хеша:
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}) {...}
, потому что (во многихобщие случаи) только истинные значения являются значимыми / возможными.Если ложные значения действительны, вы должны добавить defined()
к тесту.exists()
используется гораздо реже.Наиболее распространенный случай, вероятно, при использовании хеша в качестве набора.Например,
my %set = map { $_ => undef } 'a' .. 'z';
Использование undef
для заданных значений имеет несколько преимуществ:
- Более точно представляет намерение (значимы только ключи, а не значения).
- Все
undef
значения разделяют одно выделение (что экономит память). exists()
тесты немного быстрее (поскольку Perl не должен извлекать значение, только определите, что естьone).
У него также есть недостаток, заключающийся в том, что вы должны использовать exists()
для проверки на членство в наборе, что требует большего набора текста и сделает неправильную вещь, если вы забудете это.1048 * Еще одно место, где полезно exists
, - это проверять заблокированные хэши, прежде чем пытаться получить значение (которое вызовет исключение).