这很奇怪.下列:
$sum = !0; print $sum;
如你所料打印1.但是这个
$sum = !1; print $sum;
没有打印出来.为什么?
要小心:你所写的内容并没有按照你的想法去做.请记住,perl没有真正的布尔数据类型.它有标量,散列,列表和参考.那么它处理真/假值的方式是上下文的.除了未定义的变量,空列表,空字符串和数字0之外,perl中的所有内容都评估为"true".
那么,你的代码正在做的是取值为"false"的值的倒数,这可能是上面列表中没有的任何值.按照惯例,为了简单起见,perl返回1(尽管你不应该依赖它;它可以很好地返回包含一系列随机数的列表,因为它也会评估为"true".)
当你要求计算为"真"的值的倒数时,会发生类似的事情.实际打印出来的不是"没有",它是空字符串(''),正如我所提到的,它在布尔表达式中求值为"false".你可以检查一下:
print "This evaluates to false\n" if( (!1) eq '');
如果你问为什么perl吐出空字符串而不是其他一个"假"值,那么,这可能是因为perl被用来处理字符串,这是一个非常合理的字符串.
仅返回布尔结果的运算符将始终返回1表示true,而特殊的false值在字符串上下文中为"",在数字上下文中为0.
这是你已经得到的其他伟大答案的附录.
不是不是考虑以下代码来测试每个Perl的'not'运算符:
#!/usr/bin/perl use strict; use warnings; for( '!1', 'not 1', '~0' ) { my $value = eval; my $zero_plus = 0 + $value; print join "\n", "\nExpression: $_", "Value: '$value'", "Defined: " . defined $value, "Length: " . length($value), "Plus: " . +$value, "Plus Zero: '$zero_plus'", ''; } print "\nTest addition for a literal null string: "; print 0+'', "\n"; use Scalar::Util qw(dualvar); { # Test a dualvar my $value = dualvar 0, ''; my $zero_plus = 0+$value; print join "\n", "\nExpression: dualvar", "Value: '$value'", "Defined: " . defined $value, "Length: " . length($value), "Plus: " . +$value, "Plus Zero: '$zero_plus'", ''; }
执行它会导致以下结果.请注意警告消息:
Argument "" isn't numeric in addition (+) at test.pl line 21. Expression: !1 Value: '' Defined: 1 Length: 0 Plus: Plus Zero: '0' Expression: not 1 Value: '' Defined: 1 Length: 0 Plus: Plus Zero: '0' Expression: ~0 Value: '4294967295' Defined: 1 Length: 10 Plus: 4294967295 Plus Zero: '4294967295' Test addition for a literal null string: 0 Expression: dualvar Value: '' Defined: 1 Length: 0 Plus: Plus Zero: '0'
从中我们学到了几件事.
前两项并非令人兴奋:
!1
并且not 1
表现基本相同.
毫无疑问,~1
是不同的(不是按位).
现在,有趣的项目:
虽然我们确实收到第21行(0+''
)的警告,但添加时没有生成警告0+!1
.
这需要两个纠结
有些可疑的东西正在发生,而且鱼腥味与Perl中的特殊标量背景有关.在这种情况下,数字和字符串上下文之间的区别.并且能够创建在每个上下文中具有不同值的变量,也称为双变量.
它看起来像!1
返回一个双变量,它在数字上下文中返回0,在字符串上下文中返回null字符串.
最后的双变量测试表明,自制双变量的工作原理与之相同!1
.
像许多Perl功能一样,双变量最初似乎无视期望,并且可能令人困惑.但是,与其他功能一样,使用得当,它们可以让生活更轻松.
据我所知,doublevar是0
和''
唯一定义的值,它将在所有标量上下文中返回false.所以这是一个非常明智的回报价值 !1
.有人可能认为这undef
是一个很好的错误结果,但是一个未初始化的变量与假值无法区分.此外,打印或添加布尔结果的尝试将受到不必要的警告的困扰.
另一个着名的双变量是$!
或者$OS_ERROR
如果你use English
.在数字形式中,您将获得错误代码,以字符串形式,为您翻译错误代码.
总而言之,你没有得到任何东西,你没有得到一个空字符串,你没有得到零.
您将获得一个同时为空字符串和0的变量.