存在和定义之间有什么区别?

San*_*ing 59 perl

有什么区别

if (defined $hash{$key}) { }
Run Code Online (Sandbox Code Playgroud)

if (exists $hash{$key}) { }
Run Code Online (Sandbox Code Playgroud)

我什么时候知道使用哪个?

Mic*_*man 98

这充分证明在对的perldoc条目definedexists.这是一个快速摘要:

defined $hash{key}告诉您是否定义了给定键的值(即不是undef).用它来区分未定义的值和布尔上下文中的false值,例如0''.

exists $hash{key}告诉您是否%hash包含给定的密钥.用它来区分未定义的值和不存在的值.

这是一个最简单的例子.鉴于此哈希:

my %hash = (a => 1, b => 0, c => undef);
Run Code Online (Sandbox Code Playgroud)

以下是检索,定义和存在的结果:

# key  value  defined  exists
a          1        1       1
b          0        1       1
c      undef        0       1
d      undef        0       0
Run Code Online (Sandbox Code Playgroud)

在实践中,人们经常写作只是if ($hash{key}) {...}因为(在许多常见情况下)只有真正的价值才有意义/可能.如果false值有效,则必须添加defined()到测试中.exists()使用频率低得多.最常见的情况可能是使用散列作为集合.例如

my %set = map { $_ => undef } 'a' .. 'z';
Run Code Online (Sandbox Code Playgroud)

使用undefset值有一些优点:

  1. 它更准确地表示意图(只有键是有意义的,而不是值).
  2. 所有undef值共享一个分配(节省内存).
  3. exists() 测试稍微快一点(因为Perl不必检索值,只确定有一个值).

它还有一个缺点,你必须使用它exists()来检查集合成员资格,这需要更多的输入,如果你忘了它会做错误的事情.

另一个exists有用的地方是在尝试检索值之前探测锁定的哈希值(这将触发异常).


TLP*_*TLP 15

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
Run Code Online (Sandbox Code Playgroud)

  • @some_coder不,这是不正确的.您正在考虑[autovivification](http://en.wikipedia.org/wiki/Autovivification),当您引用多维结构时,它会出现在Perl中:您创建下面的级别来检查上面的级别.例如`if(已定义$ hash {a} {b})`将创建`$ hash {a}`如果它还不存在.但它永远不会创建`$ hash {a} {b}`. (3认同)
  • @Sandra是的,未初始化的值总是未定义的.将其视为声明和初始化之间的区别:`my $ var`存在,并包含值`undef`.`my $ var = 0`存在,并包含值0,因此定义. (2认同)

Igo*_*Oks 7

Perl 文档:

在哈希元素上使用时,已定义的值会告诉您是否定义了值,而不是哈希值是否存在.使用存在后者的目的.