關鍵字“記憶”究竟是做什麼的?
我一直在查看Etherdice的程式碼,並註意到一些變數被聲明為
ParserResult memory result;
而且我在任何文件中都沒有找到關鍵字“記憶體”。我在這裡找到的是這個解釋:
它們類似於電腦中的記憶體和硬碟儲存。合約在執行程式碼期間可以使用任意數量的記憶體(當然只要它可以支付),但是當執行停止時,記憶體的全部內容都會被擦除,下一次執行將重新開始。另一方面,儲存被持久化到區塊鏈本身中,因此下次合約執行某些程式碼時,它也可以訪問之前儲存在其儲存區域中的所有數據。
“記憶體”聲明實際上是否使值儲存在“記憶體”中?函式內的所有局部變數不都只儲存在記憶體中,而全域變數不總是儲存在區塊鏈中嗎?和這裡對“記憶”的解釋有什麼關係?
強烈建議完整閱讀有關“記憶體”的Solidity 常見問題解答,下面提供了一個片段。
乙太坊虛擬機具有三個可以儲存項目的區域。
第一個是“儲存”,所有合約狀態變數都駐留在其中。每個合約都有自己的儲存,並且在函式呼叫之間是持久的,並且使用起來非常昂貴。
第二個是“記憶體”,用於保存臨時值。它在(外部)函式呼叫之間被刪除並且使用成本更低。
第三個是棧,用來存放小的局部變數。它幾乎可以免費使用,但只能保存有限數量的值。
對於幾乎所有類型,您無法指定它們的儲存位置,因為它們每次使用時都會被複製。
所謂儲存位置很重要的類型是結構和數組。例如,如果您在函式呼叫中傳遞此類變數,則如果它們的數據可以保留在記憶體中或保留在儲存中,則不會複製它們的數據。這意味著您可以在被呼叫函式中修改它們的內容,並且這些修改在呼叫者中仍然可見。
儲存位置有預設值,具體取決於它涉及的變數類型(源):
state variables are always in storage function arguments are always in memory local variables of struct, array or mapping type reference storage by default local variables of value type (i.e. neither array, nor struct nor mapping) are stored in the stack
常見問題解答中有程式碼範例可幫助進一步解釋。
一個常見的錯誤是聲明一個局部變數(結構、數組或映射)並假設它將在記憶體中創建,儘管它將在儲存中創建。
記憶體的微妙解釋解釋了使用記憶體的 gas 成本,記憶體是一個字節數組,“從零大小開始,但可以通過簡單地訪問或儲存大於其目前大小的索引的記憶體來擴展為 32 字節塊”。