这是您已经获得的其他出色答案的附录。
不是不是不是
考虑以下测试 Perl 的每个“非”运算符的代码:
#!/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,在字符串上下文中返回空字符串。
最后的双变量测试表明自制双变量的工作方式与!1相同。
但这是件好事
与许多 Perl 功能一样,对偶变量起初似乎出乎意料,而且可能令人困惑。但是,与其他功能一样,如果使用得当,它们会让生活变得更轻松。
据我所知,0 和 '' 的对偶变量是唯一在所有标量上下文中将返回 false 的已定义值。所以对于!1 来说这是一个非常明智的返回值。有人可能会争辩说undef 是一个很好的错误结果,但是未初始化的变量无法与错误值区分开来。此外,尝试打印或添加布尔值的结果会受到不必要的警告的困扰。
另一个著名的双变量是$! 或$OS_ERROR,如果你是use English。数字形式,你得到错误代码,字符串形式,错误代码为你翻译。
它不是什么都没有,它是空的,但它没有
所以总而言之,你没有得到任何东西,你没有得到一个空字符串,你没有得到零。
你得到一个同时为空字符串和 0 的变量。