在Perl中," 0但为真"是什么意思?
有人可以解释一下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