Perl defined函数(以及许多其他函数)返回“布尔值”。
鉴于Perl实际上没有布尔类型(并使用 1 之类的值 true ,而 0 或 undef false 的)Perl语言是否准确指定了布尔值的返回值?例如,defined(undef)
会返回 0 或 undef ,是否会发生变化?
答案 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 }},0
,undef
(空字符串),甚至字符串等于""
。
所有其他值在布尔上下文中评估为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;
因此,请注意使用引用本身来表示其真实性(即其定义的内容),因为可能会创建对引用的不需要的引用。