Какая разница между существующим и определенным?

47

В чем разница между

if (defined $hash{$key}) { }

и

if (exists $hash{$key}) { }

Когда я знаю, что использовать?

Теги:

5 ответов

71
Лучший ответ

Это хорошо документировано в записях 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 полезно, - это исследовать заблокированные хэши, прежде чем пытаться извлечь значение (которое вызовет исключение).

  • 0
    Очень красиво объяснил.
  • 0
    Кроме того, defined также может быть использовано с другими типами переменных, в то время как exists вызовет ошибку, если не используется с хешем или ключом массива (или подпрограммой).
14

defined проверяет значение переменной, exists проверяет, была ли она ранее объявлена ​​/инициализирована. Если он существует, простой и простой.

например:.

$hash{$key} = undef;
# various return values:
exists  $hash{$key};  # true
defined $hash{$key};  # false
$hash{$key};          # false

$hash{$key} = 0;
# various return values:
exists  $hash{$key};  # true
defined $hash{$key};  # true
$hash{$key};          # false
exists $hash{$foo};   # false
  • 0
    И defined $hash{$foo}; #false я полагаю?
  • 2
    @Sandra Да, неинициализированные значения всегда неопределены. Думайте об этом как о разнице между объявлением и инициализацией: my $var существует и содержит значение undef . my $var = 0 существует и содержит значение 0, поэтому определено.
Показать ещё 5 комментариев
5

Perl документация:

При использовании элемента хэша определяетсявы определяете ли значение, а не существует ли ключ в хеше. Используйте существует для последней цели.

4

Как указано в perldoc на exists:

Учитывая выражение, которое указывает элемент хеша, возвращает true, если указанный элемент в хэше никогда не был инициализирован, даже если соответствующее значение undefined.

Элемент hash или array может быть истинным только в том случае, если он определен и определен только в том случае, если он существует, но обратное не обязательно выполняется.

То есть хэш может содержать элемент undefined, и если это так, то defined -check вернет false, тогда как exists -check вернет true.

Следовательно, вы должны использовать exists, если хотите знать, существует ли данная запись в хэше, и defined, если вы хотите знать, существует ли данная запись и которая определена.

  • 1
    Да. exists проверяет, содержит ли хеш заданный ключ, но не то, каково его значение, в то время как defined просматривает значение данного ключа и определяет, определено ли оно или нет (и если ключ не существует, он возвращает undef , так что работает, даже если ключа там нет.)
3

В этом примере показана разница. В общем, определенные работы для любой структуры и существуют связаны с хэшами.

my %hash=("1"=>undef);
print "exists:".exists($hash{"1"})."\n";
print "defined:".defined($hash{"1"})."\n";

Разница небольшая и не столь очевидная, поэтому ожидайте, что люди будут возиться с ней.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню