2010-08-03 92 views
13

當我在一個字符串上進行連接時,幕後發生了什麼?Perl字符串是不可變的嗎?

my $short = 'short'; 
$short .= 'cake'; 

是Perl中有效地創建一個新的字符串,然後分配給它正確的變量引用,或者是Perl語句總是自然可變的?

這個問題的動機來自我與一位同事的討論,他表示腳本語言可以使用不可變的字符串。

+0

'perldoc'中的任何實體引用將不勝感激。 – Zaid 2010-08-03 09:50:01

+0

*固體引用*可能對某些人來說過於固定:'perldoc perlguts'並尋找和圍繞'SvGROW'。否則,@eugene的迴應就是你正在尋找的。 – Dummy00001 2010-08-03 10:31:26

+0

'substr'的​​'perlfunc'文檔(既是一個左值也是一個4參數的調用)描述了自己修改字符串:增長,縮小和替換部分。 – pilcrow 2010-08-03 13:51:54

回答

17

Perl字符串可變。如果需要,Perl會自動創建新的緩衝區。

use Devel::Peek; 
my $short = 'short'; 

Dump($short); 
Dump($short .= 'cake'); 
Dump($short = ""); 

SV = PV(0x28403038) at 0x284766f4 
    REFCNT = 1 
    FLAGS = (PADMY,POK,pPOK) 
    PV = 0x28459078 "short"\0 
    CUR = 5 
    LEN = 8 
SV = PV(0x28403038) at 0x284766f4 
    REFCNT = 1 
    FLAGS = (PADMY,POK,pPOK) 
    PV = 0x28458120 "shortcake"\0 
    CUR = 9 
    LEN = 12 
SV = PV(0x28403038) at 0x284766f4 
    REFCNT = 1 
    FLAGS = (PADMY,POK,pPOK) 
    PV = 0x28458120 ""\0 
    CUR = 0 
    LEN = 12 

請注意,在第三種情況下沒有分配新的緩衝區。

+2

Perl使用realloc,它可能會也可能不會得到一個全新的緩衝區 – ysth 2010-08-03 10:06:05

+0

請注意,perl爲尾部nul分配空間,即使它不使用它來確定長度。還要注意,只要有可能,它就知道malloc庫的粒度並向上舍入分配 – ysth 2010-08-03 10:22:47

12

Perl字符串肯定是可變的。除了使用的長度和開始偏移之外,每個將存儲一個分配的緩衝區大小,並且緩衝區將根據需要進行擴展。 (開始偏移是有用的,以便/^ABC //爲不具有移動的實際數據。,比如s消費業務)

+1

在'perldoc'中是否有這個參考? – Zaid 2010-08-03 09:35:19

+0

@Zaid:不是我知道的非正式 – ysth 2010-08-03 09:52:42

0
$short = 'short'; 
print \$short; 

$short .= 'cake'; 
print \$short; 

執行此代碼我收到後「標量(0x955f468)標量(0x955f468)」 。我的答案是'可變的'。

+7

Perl標量實際上由兩個獨立的部分組成;一個固定的大小,以及一個可選的變量(取決於存儲的值的類型)大小。那裏的地址是固定大小的組件;將可變組件換出一個新組件完全可行。但實際上並非如此。 :) – ysth 2010-08-03 09:35:54