测试数组中 `undef` 与“空槽”的差异

U. *_*ndl 3 arrays perl undefined

我有一个数据结构,它具有一个带有预分配插槽(“空插槽”)的数组。编写打印例程,我想知道如何区分“空槽”和undef有价值的槽。Perl 调试器可以做到这一点,但我不知道它如何检测差异。

例子:

  DB<10> $r = []
  DB<11> $#$r=4
  DB<12> $r->[4]=undef
  DB<13> x $r
0  ARRAY(0x55d8fa6797e8)
   0  empty slot
   1  empty slot
   2  empty slot
   3  empty slot
   4  undef
Run Code Online (Sandbox Code Playgroud)

ike*_*ami 5

empty slot指的是不存在的标量(NULL指针,在 C 术语中),而undef指的是存在但未定义的标量(指向不包含值的标量的指针)。

exists可用于确定元素的值是否存在。(对于数组边界之外的元素,它也将返回 true。)

defined可用于确定元素是否已定义。(对于数组边界之外的元素和具有不存在值的元素,它也将返回 true。)

请不要在数组元素上使用exists。依赖于识别元素是否存在的代码与替代代码相比可读性和可维护性较差。文档说它甚至不可靠:

警告:强烈建议不要对数组值调用exists。删除或检查 Perl 数组元素是否存在的概念在概念上并不连贯,可能会导致令人惊讶的行为。


use feature qw( say );

sub info {
   my ($a, $i) = @_;
   if ( $i >= @$a          ) { say "$i: Non-existent slot"   }
   if ( !exists($a->[$i])  ) { say "$i: Non-existent scalar" }
   if ( !defined($a->[$i]) ) { say "$i: Undefined"           }
   if ( !$a->[$i]          ) { say "$i: False"               }
   if ( $a->[$i]           ) { say "$i: True"                }
   say "";
}

my @a;
$a[1] = undef;
$a[2] = 0;
$a[3] = 1;

info(\@a, $_) for 4,0..3;
Run Code Online (Sandbox Code Playgroud)

输出

4: Non-existent slot
4: Non-existent scalar
4: Undefined
4: False

0: Non-existent scalar
0: Undefined
0: False

1: Undefined
1: False

2: False

3: True
Run Code Online (Sandbox Code Playgroud)