Solidity

什麼時候應該使用 calldata,什麼時候應該使用記憶體?

  • January 25, 2022

我見過人們在編寫 Solidity 時同時使用memory和關鍵字。calldata具體來說,它們在聲明採用動態類型(如“結構”或“數組”)的函式參數時使用。

我應該什麼時候使用memory,什麼時候應該使用calldata

memorycalldata(以及storage)是定義儲存變數的數據區域的關鍵字。要直接回答您的問題,memory應該在聲明要儲存在記憶體中(臨時)的變數(函式參數以及函式內部的邏輯)時使用,並且calldata 必須在聲明外部函式的動態參數時使用。

考慮差異的最簡單方法calldata是儲存函式參數的不可修改、非持久性區域,其行為主要類似於記憶體。


打破這個,讓我們先來看看memorymemory的生命週期僅限於函式呼叫,旨在用於臨時儲存變數及其值。交易完成後,儲存的值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由被呼叫者分配。

引用自:https://ethereum.stackexchange.com/questions/74442