Проверить разницу между `undef` и" пустым местом "в массиве - PullRequest
3 голосов
/ 23 апреля 2020

У меня есть структура данных, в которой есть массив с предварительно выделенными слотами («пустые слоты»). При написании процедуры печати мне интересно, как я могу сделать разницу между «пустым слотом» и слотом со значением 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

1 Ответ

5 голосов
/ 23 апреля 2020

empty slot относится к скаляру, который не существует (указатель NULL, в C терминах), тогда как undef относится к скаляру, который существует, но не определен (указатель на скаляр, который содержит нет значений).

exists можно использовать для определения, существует ли значение элемента или нет. (Он также вернет true для элементов за пределами границ массивов.)

defined можно использовать для определения, определен элемент или нет. (Он также вернет true для элементов за пределами границ массива и для элементов с несуществующими значениями.)

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

ПРЕДУПРЕЖДЕНИЕ: Вызов по значениям массива настоятельно не рекомендуется. Понятие удаления или проверки существования элементов массива 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;

Вывод

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
...