比较 Perl 中的两个 undef

Rud*_*koŭ 2 perl comparison boolean logical-operators logical-or

看起来比较undef ne undef返回undef。Perl 是否有惯用的方法将其转换为 perls“布尔值”?我还发现以下内容很奇怪:

undef ne undef || 0; # 0
(undef ne undef) || 0; # undef
Run Code Online (Sandbox Code Playgroud)

您能解释一下发生了什么事吗?

ike*_*ami 6

看来比较undef ne undef有回报undef

事实并非如此。

ne返回特殊标量true(内部称为&PL_yes)或特殊标量false( &PL_no),never undef。在这种特殊情况下,它返回false.

$ perl -e'
   use v5.36;
   use experimental qw( builtin );
   use builtin qw( is_bool );

   sub inspect {
      !defined( $_[0] ) ? "[undef]" :
      is_bool( $_[0] ) ? ( $_[0] ? "[true]" : "[false]" ) :
      $_[0]
   }

   my $x = undef ne undef;  # Line 12
   say inspect( $x );       # [false]
'
Use of uninitialized value in string ne at -e line 12.
Use of uninitialized value in string ne at -e line 12.
[false]
Run Code Online (Sandbox Code Playgroud)

(结果与早期版本的 Perl 相同,但is_bool仅在 Perl v5.36 中引入。)

false是包含整数零、浮点零和空字符串的标量。

$ perl -e'
   use v5.36;
   use experimental qw( builtin );
   use builtin qw( false );

   {  my $x = "";     say 0+$x;  say "[$x]"; }  # Line 6
   say "--";
   {  my $x = 0;      say 0+$x;  say "[$x]"; }
   say "--";
   {  my $x = false;  say 0+$x;  say "[$x]"; }
'
Argument "" isn't numeric in addition (+) at -e line 6.
0
[]
--
0
[0]
--
0
[]
Run Code Online (Sandbox Code Playgroud)

我发现以下内容很奇怪:

那是因为这不是真的。这两个片段 100% 等效,并且都返回0.

$ perl -e'
   use v5.36;
   use experimental qw( builtin );
   use builtin qw( is_bool );

   sub inspect {
      !defined( $_[0] ) ? "[undef]" :
      is_bool( $_[0] ) ? ( $_[0] ? "[true]" : "[false]" ) :
      $_[0]
   }

   {  my $x =   undef ne undef   || 0;  say inspect( $x );  }  # Line 12  # 0
   {  my $x = ( undef ne undef ) || 0;  say inspect( $x );  }  # Line 13  # 0
'
Use of uninitialized value in string ne at -e line 12.
Use of uninitialized value in string ne at -e line 12.
0
Use of uninitialized value in string ne at -e line 13.
Use of uninitialized value in string ne at -e line 13.
0
Run Code Online (Sandbox Code Playgroud)

(结果与早期版本的 Perl 相同,但is_bool仅在 Perl v5.36 中引入。)


您能解释一下发生了什么事吗?

ne是一个字符串比较运算符。因此它首先将其操作数转换为字符串。转换undef为字符串会产生空字符串,并发出警告。由于空字符串等于空字符串,ne因此返回假值,特别是特殊false标量。

由于false是假值,因此||计算并返回其右侧值 ( 0)。


Perl 是否有惯用的方法将其转换为 perls“布尔值”?

获取truefalse从某个值获取的最简单方法是将其取反两次。

my $normalized = !!$x;
Run Code Online (Sandbox Code Playgroud)

获取1if true 或0if false 的最简单方法是使用条件运算符。

my $normalized = $x ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)