摘自:https://solidity-cn.readthedocs.io/zh/develop/types.html?highlight=storage#index-14
对于占位空间超过256位类型,需要慎重,否则存贮开销较大,因此需要考虑是存储在memory(临时存贮)还是storage(存储状态变量的地方)中;
所有复杂类型(数组、结构)都有一个额外属性“数据位置”,storage/memory;
函数参数、返回值均为memory;
局部变量默认位置为storage;
状态变量的位置强制为storage;
calldata是一块只读的、不会永久存贮的位置,用来存储函数参数。外部函数的参数(非返回值)被强制设置为calldata,效果类似memory;
状态变量赋值局部变量时仅传递一个引用,因此状态变量改变,局部变量同时改变;
从一个memory引用类型向另一个memory引用类型赋值并不会创建拷贝;
pragma solidity ^0.4.0;
contract C {
uint[] x; // x 的数据存储位置是 storage
// memoryArray 的数据存储位置是 memory
function f(uint[] memoryArray) public {
x = memoryArray; // 将整个数组拷贝到 storage 中,可行
var y = x; // 分配一个指针(其中 y 的数据存储位置是 storage),可行
y[7]; // 返回第 8 个元素,可行
y.length = 2; // 通过 y 修改 x,可行
delete x; // 清除数组,同时修改 y,可行
// 下面的就不可行了;需要在 storage 中创建新的未命名的临时数组, /
// 但 storage 是“静态”分配的:
// y = memoryArray;
// 下面这一行也不可行,因为这会“重置”指针,
// 但并没有可以让它指向的合适的存储位置。
// delete y;
g(x); // 调用 g 函数,同时移交对 x 的引用
h(x); // 调用 h 函数,同时在 memory 中创建一个独立的临时拷贝
}
function g(uint[] storage storageArray) internal {}
function h(uint[] memoryArray) public {}
}