數(shù)據(jù)地址

2022-05-12 17:01 更新

每個引用類型都有一個附加注釋,即“數(shù)據(jù)位置”,關(guān)于它的存儲位置。共有三個數(shù)據(jù)位置 memory:storage和calldata。Calldata 是存儲函數(shù)參數(shù)的不可修改、非持久性區(qū)域,其行為主要類似于內(nèi)存。

筆記

如果可以,請嘗試calldata用作數(shù)據(jù)位置,因為它可以避免復(fù)制并確保無法修改數(shù)據(jù)。具有數(shù)據(jù)位置的數(shù)組和結(jié)構(gòu)calldata 也可以從函數(shù)返回,但不可能分配此類類型。

筆記

在 0.6.9 版之前,引用類型參數(shù)的數(shù)據(jù)位置僅限 calldata于外部函數(shù)、memory公共函數(shù)以及 memory內(nèi)部storage和私有函數(shù)中。現(xiàn)在memory,calldata無論其可見性如何,都允許在所有功能中使用。

筆記

在 0.5.0 版本之前,數(shù)據(jù)位置可以省略,并且會根據(jù)變量的類型、函數(shù)類型等默認(rèn)到不同的位置,但現(xiàn)在所有復(fù)雜類型都必須給出明確的數(shù)據(jù)位置。

數(shù)據(jù)位置和分配行為?

數(shù)據(jù)位置不僅與數(shù)據(jù)的持久性有關(guān),還與分配的語義有關(guān):

  • storagememory(或 from )之間的分配calldata總是創(chuàng)建一個獨立的副本。

  • 分配 from memorytomemory僅創(chuàng)建參考。這意味著對一個內(nèi)存變量的更改在引用相同數(shù)據(jù)的所有其他內(nèi)存變量中也可見。

  • storage本地存儲變量的賦值也只分配一個引用。

  • 所有其他分配storage始終復(fù)制。這種情況的示例是對狀態(tài)變量或存儲結(jié)構(gòu)類型的局部變量成員的賦值,即使局部變量本身只是一個引用。

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;

contract C {
    // The data location of x is storage.
    // This is the only place where the
    // data location can be omitted.
    uint[] x;

    // The data location of memoryArray is memory.
    function f(uint[] memory memoryArray) public {
        x = memoryArray; // works, copies the whole array to storage
        uint[] storage y = x; // works, assigns a pointer, data location of y is storage
        y[7]; // fine, returns the 8th element
        y.pop(); // fine, modifies x through y
        delete x; // fine, clears the array, also modifies y
        // The following does not work; it would need to create a new temporary /
        // unnamed array in storage, but storage is "statically" allocated:
        // y = memoryArray;
        // This does not work either, since it would "reset" the pointer, but there
        // is no sensible location it could point to.
        // delete y;
        g(x); // calls g, handing over a reference to x
        h(x); // calls h and creates an independent, temporary copy in memory
    }

    function g(uint[] storage) internal pure {}
    function h(uint[] memory) public pure {}
}


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號