在Perl中," 0但为真"是什么意思?

时间:2020-03-06 14:41:22  来源:igfitidea点击:

有人可以解释一下Perl中的字符串" 0 but true"到底是什么意思吗?据我了解,它在整数比较中等于零,但是当用作布尔值时,其计算结果为true。这样对吗?这是语言的正常行为,还是这是特殊的字符串,在解释器中被视为特殊情况?

解决方案

在整数上下文中,其计算结果为0(字符串开头的数字部分)且为零。在标量上下文中,它是一个非空值,所以它是正确的。

  • if(int(" 0 but true")){打印"零"; }(无输出)
  • if(" 0 but true"){打印" true"; }(打印真实)

当我们要编写一个返回整数值或者false或者undef的函数(即针对错误情况)时,必须注意零值。返回它是错误的,并且不应指示错误情况,因此返回" 0但为真"会使函数返回值true,而在完成数学运算后仍返回零。

这是该语言的正常行为。引用perlsyn联机帮助页:

The number 0, the strings '0' and "", the empty list (), and undef
  are all false in a boolean context. All other values are true.  Negation
  of a true value by ! or not returns a special false value.
  When evaluated as a string it is treated as "", but as a number, it is
  treated as 0.

因此,需要有一种方法可以从希望返回" 0"作为(成功的)返回值的系统调用中返回" 0",并提供一种通过实际返回假值来指示故障情况的方法。 " 0但正确"达到了这个目的。

除了其他人所说的以外," 0但为真"是特殊情况,因为它不会在数字上下文中发出警告:

$ perl -wle 'print "0 but true" + 3'
3
$ perl -wle 'print "0 but crazy" + 3'
Argument "0 but crazy" isn't numeric in addition (+) at -e line 1.
3

" 0但为真"是一个字符串,与其他字符串一样,但是由于perl的语法,它可以用于一个有用的目的,即从函数返回整数零而结果不为" false"(在perl看来)。

字符串不必为" 0,但为true"。从布尔意义上讲," 0但假"仍然是"真"。

考虑:

if(x)

for x:        yields:
1             -> true
0             -> false
-1            -> true
"true"        -> true
"false"       -> true
"0 but true"  -> true
int("0 but true") ->false

所有这些的结果是我们可以拥有:

sub find_x()

并使此代码能够输出" 0"作为其输出:

if($x = find_x)
{
   print int($x) . "\n";
}

0在Perl(以及与C相关的其他语言)中表示false。在大多数情况下,这是一种合理的行为。其他语言(例如,Lua)将0视为true,并提供另一个令牌(通常为nil或者false)来表示非true值。

如果我们想返回一个数字,或者如果该函数由于某种原因而失败,则返回一个假值,这是Perl方式无法正常工作的情况。例如,如果我们编写一个函数来从文件中读取一行并返回该行上的字符数。该函数的常见用法可能是这样的:

while($c = characters_in_line($file)){
    ...
};

请注意,如果特定行上的字符数为0,则while循环将在文件末尾之前结束。因此,characters_in_line函数应在特殊情况下为0个字符,并返回" 0但为true"。这样,该函数将在while循环中按预期工作,但如果将其用作数字,也将返回正确的答案。

请注意,这不是该语言的内置部分。而是利用Perl的能力将字符串解释为数字。因此,有时会使用其他st刺代替。例如,DBI使用" 0E0"。在数字上下文中求值时,它们返回0,但在布尔上下文中返回false。

我们可能还会看到Perl代码中使用的字符串" 0E0",它的含义相同,其中0E0仅表示以指数表示法编写的0。但是,由于Perl仅将" 0","''或者undef视为假,因此在布尔上下文中其结果为true。

另一个" 0但为真"的示例:

DBI模块使用" 0E0"作为不影响任何记录的UPDATE或者DELETE查询的返回值。在布尔上下文中(指示查询已正确执行),它的计算结果为true;在数字上下文中,其值表示为0,指示查询未更改任何记录。

我刚刚发现证明字符串" 0 but true"实际上是内置在解释器中的,就像这里的某些人已经回答的那样:

$ strings /usr/lib/perl5/5.10.0/linux/CORE/libperl.so | grep -i true
Perl_sv_true
%-p did not return a true value
0 but true
0 but true