各种逻辑运算符不会返回空字符串,它们会在所有三种简单标量类型中返回假或真值。它只是看起来像它因为print
迫使其参数字符串上下文中返回一个空字符串:
#!/usr/bin/perl
use strict;
use warnings;
use Devel::Peek;
my $t = 5 > 4;
my $f = 5 < 4;
Dump $t;
Dump $f;
输出:
SV = PVNV(0x100802c20) at 0x100827348
REFCNT = 1
FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 1
NV = 1
PV = 0x100201e60 "1"\0
CUR = 1
LEN = 16
SV = PVNV(0x100802c40) at 0x100827360
REFCNT = 1
FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x100208ca0 ""\0
CUR = 0
LEN = 16
对于那些不熟悉的Perl 5内部,一个PVNV
是一个标量结构保存所有三种简单标量类型(整数IV
,双精度浮点数NV
和字符串PV
)。标记IOK
,NOK
和POK
表示整数,双精度和字符串值全部同步(对于同步中的某些定义),因此可以使用它们中的任何一个(即,如果使用它们,则不需要进行任何转换作为整数,双精度或字符串)。
我假定空字符串被选为虚假字符串,因为它
更小,
更符合虚假字符串的想法,而不是"0"
。忽略我关于它变小的说法,""
和"1"
都是相同的大小:16个字符。它在转储中说得很对。 Perl 5为字符串增加了额外的空间,使它们能够快速增长。
哦,我讨厌你。在研究中,我发现我在perlopquick
中撒谎,现在必须找到一种解决办法。如果只有你像所有其他的羊一样,只是接受Perl 5的表面怪异,那么我的工作量就会减少。
答案在EDIT部分中的问题:
会如何使用字符串的虚假值改变现有代码的意思是真正的字符串表示(例如“假”)?
约约PL_sv_yes和PL_sv_no(由比较运算符返回的标准地真假值)唯一特殊的事情是,他们是只读的,由perl
不是正在运行的程序创建的。如果你改变他们,这不会改变感实性测试,所以它被设置为一个"false"
将PL_sv_no作为真正的治疗。你甚至可以自己做(此代码将停止Perl的5.18和最新的Perl之间在某些时候工作)使用的perl
无证特点:
#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util qw/dualvar/;
BEGIN {
# use the undocumented SvREADONLY function from Internals to
# modify a reference to PL_sv_no's readonly flag
# note the use of & to make the compiler not use SvREADONLY's
# prototype, yet another reason prototypes are bad and shouldn't
# be used
&Internals::SvREADONLY(\!!0, 0);
# set PL_sv_no to a dualvar containing 0 and "false"
${\!!0} = dualvar 0, "false";
}
if (5 < 4) {
print "oops\n";
}
输出
opps
这是因为感实性测试检查在弦首先。
我们可以说在这样的变化之后改变语义的代码比它本来不那么健壮/正确吗?
将直线上升打破。即使您限制自己将其设置为int 0或字符串“0”(两者均为false),它也会破坏一些有效的代码。
我猜字符串上下文是Perl中如此普遍,导致理智语义唯一的选择是,如果布尔值后轮跳闸,并从一个字符串保存它的价值...
是。
可能的重复[为什么!1在Perl中什么都不给我?](http://stackoverflow.com/questions/1134962/why-does-1-give-me-nothing-in-perl) – Thilo 2016-09-06 01:21:47