Perl 内部结构详解 -- PerlGuts Illustrated (2 SV)
_SV_HEAD and struct sv下面来看一下最简单的类型struct sv,代表了SV,GV,CV,AV,HV,IO的通用结构。如下图所示: 第一个字段Any可以指向任意结构,除了RV,所有的其他类型都是由Any指向的附加数据来实现。 常见的flags见下边具体示例。 C:&;perl -MDevel::Peek -e "Dump $a" SV = NULL(0x0) at 0x182a9fc ? REFCNT = 1 ? FLAGS = () C:&;perl -MDevel::Peek -e "Dump $a" SV = RV(0x299158) at 0x29914c ? REFCNT = 1 ? FLAGS = (TEMP,ROK) ? RV = 0x182a9fc ? SV = NULL(0x0) at 0x182a9fc ? ? REFCNT = 2 ? ? FLAGS = () SvIV and SvNV整数和小树,结构如图所示: C:&;perl -MDevel::Peek -e "$a = 123; Dump $a" SV = IV(0x182aa20) at 0x182aa24 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 123 C:&;perl -MDevel::Peek -e "$a = 123.9; Dump $a" SV = NV(0x184882c) at 0x182aa2c REFCNT = 1 FLAGS = (NOK,pNOK) NV = 123.9 SvPV字符串,结构如图所示: 除了SV以外,额外的结构xpv被分配,它包含三部分: PVX 指向实际的字符串。 POK标记表示PVX所指向的内存包含有效字符串,否则所包含的字符串无效。 C:&;perl -MDevel::Peek -e "$a = 't'; Dump $a" SV = PV(0x296fec) at 0x182aa24 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x182472c "t" CUR = 1 LEN = 4 C:&;perl -MDevel::Peek -e "$a = 'test'; Dump $a" SV = PV(0x296fec) at 0x182aa2c REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x182466c "test" CUR = 4 LEN = 8 (随着长度增加,以4为增量) C:&;perl -MDevel::Peek -e "$a = 'test'; $a = undef; Dump $a" SV = PV(0x296ffc) at 0x182aa34 REFCNT = 1 FLAGS = () (包含字符串,但是无效) PV = 0x1824674 "test" CUR = 4 LEN = 8 SvOOK为了提高移除字符串开头字符的速度,使用了OOK标记,IVX存储着偏移量,结构如图所示: C:&;perl -MDevel::Peek -e "$a = 'xtesting'; $a=~s/.//; Dump $a" SV = PVIV(0x182005c) at 0x182aa4c REFCNT = 1 FLAGS = (POK,OOK,pPOK) IV = 1 (OFFSET) PV = 0x182467d ( "x" . ) "testing" CUR = 7 LEN = 11 SvPVIV and SvPVNV类似字符串,但是PVIV储存了额外的整数或者小数信息,可以根据flag直接进行数学运算,结构如图所示: C:&;perl -MDevel::Peek -e "$a = '123.0'; 0+$a; Dump $a" SV = PVNV(0x29838c) at 0x182aa34 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 123 NV = 123 PV = 0x1824674 "123.0" CUR = 5 LEN = 8 C:&;perl -MDevel::Peek -e "$a = '123testing'; 0+$a; Dump $a" SV = PVNV(0x298394) at 0x182aa34 REFCNT = 1 FLAGS = (POK,pPOK) IV = 123 NV = 123 PV = 0x1824674 "123testing" CUR = 10 LEN = 12 SvRV类似指针,指向任意其他结构,结构如图所示: C:&;perl -MDevel::Peek -e "$a = '123testing'; $b = $a ; Dump $b" SV = RV(0x182ab68) at 0x182ab5c REFCNT = 1 FLAGS = (ROK) RV = 0x182aa4c SV = PV(0x296ffc) at 0x182aa4c REFCNT = 2 FLAGS = (POK,pPOK) PV = 0x182467c "123testing" CUR = 10 LEN = 12 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |