存储非常昂贵
Solidity 使用storage(存储)是相当昂贵的,“写入”操作尤其贵。
这是因为,无论是写入还是更改一段数据, 这都将永久性地写入区块链。需要在全球数千个节点的硬盘上存入这些数据,随着区块链的增长,拷贝份数更多,存储量也就越大。这是需要成本的!
为了降低成本,不到万不得已,避免将数据写入存储。这也会导致效率低下的编程逻辑 - 比如每次调用一个函数,都需要在 memory(内存) 中重建一个数组,而不是简单地将上次计算的数组给存储下来以便快速查找。
在大多数编程语言中,遍历大数据集合都是昂贵的。但是在 Solidity 中,使用一个标记了external view的函数,遍历比 storage 要便宜太多,因为 view 函数不会产生任何花销(gas可是真金白银啊!)。
我们将在下一章讨论for循环,现在我们来看一下看如何如何在内存中声明数组。
在内存中声明数组
在数组后面加上 memory关键字, 表明这个数组是仅仅在内存中创建,不需要写入外部存储,并且在函数调用结束时它就解散了。与在程序结束时把数据保存进 storage 的做法相比,内存运算可以大大节省gas开销 -- 把这数组放在view里用,完全不用花钱。
以下是申明一个内存数组的例子:
function getArray() external pure returns(uint[]) {
// 初始化一个长度为3的内存数组
uint[] memory values = new uint[](3);
// 赋值
values.push(1);
values.push(2);
values.push(3);
// 返回数组
return values;
}
复制代码这个小例子展示了一些语法规则,下一章中,我们将通过一个实际用例,展示它和 for 循环结合的做法。
注意:内存数组 必须 用长度参数(在本例中为3)创建。目前不支持 array.push()之类的方法调整数组大小,在未来的版本可能会支持长度修改。
实战演习
我们要要创建一个名为getPetsByOwner的函数,它以uint []数组的形式返回某一用户所拥有的所有区块宠物。
声明一个名为result的变量,其类型是 uint [] memory(内存变量数组)
将其设置为一个新的 uint 类型数组。数组的长度为该 _owner 所拥有的区块宠物数量,这可通过调用 ownerPetCount [_owner] 来获取。
返回 result 。目前它只是个空数列,我们到下一章去实现它。


