Re: [問題] 參照 變數宣告及記憶體位置問題

看板Perl作者 (啊)時間1年前 (2023/02/13 21:44), 1年前編輯推噓1(101)
留言2則, 2人參與, 5月前最新討論串2/2 (看更多)
基本上你可以預期一個純量變數會對應到記憶體中的固定一小片空間,其位置幾 乎 [^1] 不會變。但若是用 print 去印的某個內容物是參照的變數的話, 印出來的後面那個數字代表的不是變數本身的位置,而是其內容物的位置。 以下面這個例子而言,印 "$Ref" 會顯示出 $AAA 的位置。 my $AAA = 0; $Ref = \$AAA; print "1:$Ref\n"; 如果你想要得知 $Ref 的位置,可以透過 Devel::Peek 模組的 Dump() 函式: my $AAA = 0; $Ref = \$AAA; Dump($Ref); 然後會在 STDERR 上看到這一大片表示純量變數內部結構的文字: SV = IV(0xe33cf4) at 0xe33cf8 REFCNT = 1 FLAGS = (ROK) RV = 0xe33cd8 SV = IV(0xe33cd4) at 0xe33cd8 REFCNT = 2 FLAGS = (IOK,pIOK) IV = 0 其中 16 進位數字就是位置,而前面 SV / IV 這兩個關鍵字對應到的是 perl5.git 原始碼中的資料結構。SV 對應到純量變數 (scalar variable),IV 對應到整數數值 (integer value)。還有很多其他種類,很有興趣的的話可以略 看一下 perlguts 這份文件: https://perldoc.perl.org/perlguts 其中第一行 SV 後面的 at 0xe33cf48 就是 $Ref 的位置, 而第五行的 SV = ... at 0xe33cd8 則是 $AAA 的位置。 回到你的原問題: 為什麼我使用my宣告後的第二次重新指定變數內容會讓Perl指向新的記憶體位置, 而沒有宣告的部份卻是指向一樣的位置? 我認爲這是爲了讓實做上方便而必然的結果,如果從 `my` 的文件這段來看: https://perldoc.perl.org/functions/my (或: perldoc -f my) Redeclaring a variable in the same scope or statement will "shadow" the previous declaration, creating a new instance and preventing access to the previous one. 既然同名變數第 n+1 次的宣告必須將第 n 次的宣告內容蓋掉,那要不就是用沿用同一個容器, 把舊的值清理乾淨,相關副作用全部正確發動完畢之後再後裝新的值進來,要不就是準備一個新容器, 讓後舊的放在原地讓 GC 機制 (ref count) 去清理。 考慮到參照物可能是所有資料型別,第二種準備新容器的做法應該比較省事。 簡單講就是:在同一段語意範圍內宣告了兩個 $AAA 的話,相當於是兩個不同變數。 只是第二個出現後第一個就變成找不到了。 [^1]: 我一時之間還真想不到有沒有甚麼狀況會變。我猜如果 fork() 後再修改內容, 讓 copy-on-write 發生,應該就會變。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 125.56.75.152 (日本) ※ 文章網址: https://www.ptt.cc/bbs/Perl/M.1676295893.A.307.html ※ 編輯: gugod (125.56.75.152 日本), 02/13/2023 21:51:09

02/14 06:26, 1年前 , 1F
02/14 06:26, 1F

12/25 22:52, 5月前 , 2F
12/25 22:52, 2F
文章代碼(AID): #1ZwZxLC7 (Perl)
文章代碼(AID): #1ZwZxLC7 (Perl)