Какая разница между существующим и определенным? - PullRequest
56 голосов
/ 30 июня 2011

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

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

и

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

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

Ответы [ 5 ]

93 голосов
/ 30 июня 2011

Это хорошо задокументировано в записях 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 для заданных значений имеет несколько преимуществ:

  1. Более точно представляет намерение (значимы только ключи, а не значения).
  2. Все undef значения разделяют одно выделение (что экономит память).
  3. exists() тесты немного быстрее (поскольку Perl не должен извлекать значение, только определите, что естьone).

У него также есть недостаток, заключающийся в том, что вы должны использовать exists() для проверки на членство в наборе, что требует большего набора текста и сделает неправильную вещь, если вы забудете это.1048 * Еще одно место, где полезно exists, - это проверять заблокированные хэши, прежде чем пытаться получить значение (которое вызовет исключение).

15 голосов
/ 30 июня 2011

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
7 голосов
/ 30 июня 2011

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

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

4 голосов
/ 30 июня 2011

Как указано в perldoc для exists:

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

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

То есть, хэш можетсодержат неопределенный элемент, и в этом случае проверка defined вернет false, тогда как проверка exists вернет true.

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

3 голосов
/ 30 июня 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...