返回布尔实际返回的Perl函数是什么

时间:2012-11-22 21:33:37

标签: perl boolean return

Perl defined函数(以及许多其他函数)返回“布尔值”。

鉴于Perl实际上没有布尔类型(并使用 1 之类的值 true ,而 0 undef false )Perl语言是否准确指定了布尔值的返回值?例如,defined(undef)会返回 0 undef ,是否会发生变化?

4 个答案:

答案 0 :(得分:14)

在几乎所有情况下(即除非有理由不这样做),Perl会返回两个静态分配的标量之一:&PL_sv_yes(对于true)和&PL_sv_no(对于false)。这是他们的详细信息:

>perl -MDevel::Peek -e"Dump 1==1"
SV = PVNV(0x749be4) at 0x3180b8
  REFCNT = 2147483644
  FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
  IV = 1
  NV = 1
  PV = 0x742dfc "1"\0
  CUR = 1
  LEN = 12

>perl -MDevel::Peek -e"Dump 1==0"
SV = PVNV(0x7e9bcc) at 0x4980a8
  REFCNT = 2147483647
  FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
  IV = 0
  NV = 0
  PV = 0x7e3f0c ""\0
  CUR = 0
  LEN = 12

yes是三重变量(IOK,NOK和POK)。它包含一个等于1的有符号整数(IV),一个等于1的浮点数(NV)和一个等于1的字符串(PV)。

no也是三重变量(IOK,NOK和POK)。它包含一个等于0的有符号整数(IV),一个等于0的浮点数(NV)和一个空字符串(PV)。这意味着它将字符串化为空字符串,并将其编号为0.它既不等于空字符串

>perl -wE"say 0+(1==0);"
0

>perl -wE"say 0+'';"
Argument "" isn't numeric in addition (+) at -e line 1.
0

也不是0

>perl -wE"say ''.(1==0);"


>perl -wE"say ''.0;"
0

无法保证始终如此。并且没有理由依赖于此。如果您需要特定值,可以使用类似

的内容
my $formatted = $result ? '1' : '0';

答案 1 :(得分:6)

它们返回一个特殊的false值,在字符串上下文中为“”,但在数字上下文中为0(没有非数字警告)。真正的价值并不是那么特别,因为它在任何一种情况下都是1。 defined()返回undef。

(您可以使用例如Scalar::Util::dualvar(0,"")创建类似的值。)

答案 2 :(得分:3)

由于这是官方手册页,我会说它没有指定确切的返回值。如果Perl文档讨论布尔值,那么它几乎总是讨论在布尔上下文中评估所述值:if (defined ...)print while <>等。在这样的上下文中,几个值计算为false:{{1 }},0undef(空字符串),甚至字符串等于""

所有其他值在布尔上下文中评估为true,包括臭名昭着的示例"0"

由于文档含糊不清,我不会依赖"0 but true"返回未定义案例的任何特定值。但是,如果您只是在布尔上下文中使用defined()而不将其与特定值进行比较,那么您将永远都可以。

好的:defined()

不便携/未来证明:print "yes\n" if defined($var)或类似的东西

答案 3 :(得分:3)

它可能永远不会改变,但perl没有指定defined(...)返回的确切布尔值。

使用布尔值时,好的代码不应该依赖于用于true和false的实际值。

示例:

# not so great code:
my $bool = 0;   #
...
if (some condition) {
  $bool = 1;
}

if ($bool == 1) { ... }

# better code:
my $bool;       # default value is undef which is false

$bool = some condition;

if ($bool) { ... }

99.9%的时间没有理由关心用于布尔值的值。 也就是说,在某些情况下,最好使用显式0或1而不是值的布尔值。例如:

sub foo {
    my $object = shift;
    ...
    my $bool = $object;
    ...
    return $bool;
}

意图是使用引用或foo()调用undef,如果未定义$object,则应返回false。问题是如果定义$object foo()将返回对象本身,从而创建对该对象的另一个引用,这可能会干扰其垃圾收集。所以这里最好使用一个显式的布尔值,即:

  my $bool = $object ? 1 : 0;

因此,请注意使用引用本身来表示其真实性(即其定义的内容),因为可能会创建对引用的不需要的引用。