有許多不同類型的標量。
- SvNULL不能保存除undef以外的任何值。
- SvIV能夠持有IV,UV或RV。
- SvNV能夠容納NV。
- SvPV能夠容納一個PV。
- SvPVIV能夠持有PV,以及IV,UV或RV。
- ...
AV,HV,CV,GV其實只是類型的標量太大。
注意我說「有能力」持有。你可以把標量看作是對象,而上面是類和子類。以上每個都有不同的結構。
擁有這些不同類型的標量可以節省內存。
SvIV(能夠容納IV的最小標量類型)小於SvPV(能夠容納PV的最小標量類型)。
$ perl -le'
use Devel::Size qw(total_size);
use Inline C => <<'\''__EOI__'\'';
void upgrade_to_iv(SV* sv) {
SvUPGRADE(sv, SVt_IV);
}
void upgrade_to_pv(SV* sv) {
SvUPGRADE(sv, SVt_PV);
}
__EOI__
{ my $x; upgrade_to_iv($x); print total_size($x); }
{ my $x; upgrade_to_pv($x); print total_size($x); }
'
24
40
使用SvIV而不是SvPV可節省每個引用16個字節。
瑣事:SvIV的IV插槽和SvPV的PV插槽位於相同的偏移處。見[illguts](http://search.cpan.org/dist/illguts/) – ikegami
謝謝您的深刻解答!在我自己的實驗中,我嘗試着和沒有祝福;在前一種情況下,產生了一個PVMG結構,其中包含一個PVX槽,增加了我的困惑。我現在只是重試而沒有祝福,而且在您寫作時確實會分配一個SvIV結構。我沒有想過節省內存,但現在完全合理! – Edward
重新評論:剛剛嘗試過,令我驚訝的是,SvPVX和SvIVX確實返回相同的(存儲)值!鑑於SvIV和SvPV的結構已經通過各種版本的Perl發展,我想我不應該依賴這個,特別是因爲SvPOK不是真的。 – Edward