Solidity
什麼時候應該使用 calldata,什麼時候應該使用記憶體?
我見過人們在編寫 Solidity 時同時使用
memory
和關鍵字。calldata
具體來說,它們在聲明採用動態類型(如“結構”或“數組”)的函式參數時使用。我應該什麼時候使用
memory
,什麼時候應該使用calldata
?
memory
和calldata
(以及storage
)是定義儲存變數的數據區域的關鍵字。要直接回答您的問題,memory
應該在聲明要儲存在記憶體中(臨時)的變數(函式參數以及函式內部的邏輯)時使用,並且calldata
必須在聲明外部函式的動態參數時使用。考慮差異的最簡單方法
calldata
是儲存函式參數的不可修改、非持久性區域,其行為主要類似於記憶體。打破這個,讓我們先來看看
memory
。memory
的生命週期僅限於函式呼叫,旨在用於臨時儲存變數及其值。交易完成後,儲存的值memory
不會保留在網路上。關於記憶體的一些值得注意的實現細節如下:
- 它可以用於函式聲明參數以及函式邏輯內
- 它是可變的(它可以被覆蓋和改變)
- 它是非持久的(事務完成後值不持久)
這個答案是理解記憶的一個很好的資源。
calldata
與記憶體非常相似,因為它是儲存項目的數據位置。它是一個包含函式參數的特殊數據位置,僅可用於外部函式呼叫參數。來自 Solidity文件:Calldata 是儲存函式參數的不可修改、非持久性區域,其行為主要類似於記憶體。
這是使用最便宜的位置,但它的大小有限。特別是,這意味著函式的參數數量可能會受到限制。1值得注意的實施細節
calldata
如下:
- 只能用於函式聲明參數(不能用於函式邏輯)
- 它是不可變的(它不能被覆蓋和改變)
- 它必須用於外部函式的動態參數
- 它是非持久的(事務完成後值不持久)
以下是使用and的有效程式碼範例:
memory``calldata
pragma solidity 0.5.11; contract Test { string stringTest; function memoryTest(string memory _exampleString) public returns (string memory) { _exampleString = "example"; // You can modify memory string memory newString = _exampleString; // You can use memory within a function's logic return newString; // You can return memory } function calldataTest(string calldata _exampleString) external returns (string memory) { // cannot modify _exampleString // but can return it return _exampleString; } }
編輯基於 Tjaden Hess 的評論
考慮差異以及應如何使用它們的一種好方法
calldata
是由呼叫者分配,而memory
由被呼叫者分配。