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


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

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

и

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

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

5   51   2011-06-30 16:17:18

5 ответов:

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

он также имеет тот недостаток, что вы должны использовать exists() чтобы проверить набор членства, который требует больше ввода и будет делать неправильные вещи, если вы забудете его.

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

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

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

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

как говорится в perldoc on exists:

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

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

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

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

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

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

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