数据位置(Data location)
复杂类型,如数组(arrays)
和数据结构(struct)
在Solidity中有一个额外的属性,数据的存储位置。可选为memory
和storage
。
memory
存储位置同我们普通程序的内存一致。即分配,即使用,越过作用域即不可被访问,等待被回收。而在区块链上,由于底层实现了图灵完备,故而会有非常多的状态需要永久记录下来。比如,参与众筹的所有参与者。那么我们就要使用storage
这种类型了,一旦使用这个类型,数据将永远存在。
基于程序的上下文,大多数时候这样的选择是默认的,我们可以通过指定关键字storage
和memory
修改它。
默认的函数参数,包括返回的参数,他们是memory
。默认的局部变量是storage
的1。而默认的状态变量(合约声明的公有变量)是storage
。
另外还有第三个存储位置calldata
。它存储的是函数参数,是只读的,不会永久存储的一个数据位置。外部函数
的参数(不包括返回参数)被强制指定为calldata
。效果与memory
差不多。
数据位置指定非常重要,因为不同数据位置变量赋值产生的结果也不同。在memory
和storage
之间,以及它们和状态变量
(即便从另一个状态变量)中相互赋值,总是会创建一个完全不相关的拷贝。
将一个storage
的状态变量,赋值给一个storage
的局部变量,是通过引用传递。所以对于局部变量的修改,同时修改关联的状态变量。但另一方面,将一个memory
的引用类型赋值给另一个memory
的引用,不会创建另一个拷贝。
|
|
下面来看下官方的例子说明:
|
|
总结
强制的数据位置(Forced data location)
外部函数(External function)
的参数(不包括返回参数)强制为:calldata
状态变量(State variables)
强制为:storage
默认数据位置(Default data location)
- 函数参数(括返回参数:
memory
- 所有其它的局部变量:
storage
特别注意的是,storage是相对昂贵的,这直接涉及到部署合约时产生的gas。
更多请查看关于数据位置的进一步挖掘: http://me.tryblockchain.org/solidity-data-location.html