为什么Perl的规范“真实”和“虚假”价值PVNV内部?

时间:2014-06-06 06:46:41

标签: perl perlguts

Perl具有规范的“true”和“false”值,用于!not布尔否定的情况。

#!/usr/bin/env perl

use strict;
use warnings;

use Data::Dumper;

print Dumper !1;    # outputs $VAR1 = '';
print Dumper !!1;   # outputs $VAR1 = 1;

到目前为止一切都很好。

但是,当我使用Devel::Peek查看值时,很明显它们不等同于文字''1,它们都是SV PVNV值。

$ perl -MDevel::Peek -E 'Dump ""; Dump !1;' 2>&1 | grep '^SV'
SV = PV(0x15e5140) at 0x1603298
SV = PVNV(0x15e3010) at 0x7814b0

$ perl -MDevel::Peek -E 'Dump 1; Dump !!1;' 2>&1 | grep '^SV'
SV = IV(0xfce228) at 0xfce238
SV = PVNV(0xfae030) at 0x7819f0

我已经使用Perl 5.16.3和Perl 5.20.0进行了测试。

PVNV不是比简单的IV大得多吗?这是Perl交易记忆的速度吗?

2 个答案:

答案 0 :(得分:5)

不仅仅是布尔否定;这些值由许多内置函数返回。

实际上没有内存问题,因为每个内存只有一个实例。

特别是的假值必须是PVNV,因为它的字符串值''及其数值0不能相互导出(至少不会触发警告) )。

答案 1 :(得分:1)

我相信这里的答案是肯定的,PVNV更大,但Perl只保留一个真值的副本和一个假值的副本在内存中,所以它不像你的那样在脚本中有大量布尔值的内存不足。

我从此REFCNT输出中的引用计数(Devel::Peek)中获取该内容:

$ perl -MDevel::Peek -E 'Dump !1; Dump !!1;'  2>&1 | grep REFCNT
  REFCNT = 2147483646
  REFCNT = 2147483644