Solidity 数组
数组是一种数据结构,它是存储同类元素的有序集合。
数组中的特定元素由索引访问,索引值从 0 开始。例如,声明一个数组变量,如 numbers,可以使用 numbers[0]、numbers[1] 表示单个变量。
数组大小可以是固定大小的,也可以是动态长度的。
对于 storage 数组,元素可以是任意类型(其他数组、映射或结构)。
对于 memory 数组,元素类型不能是映射类型,如果它是一个 public 函数的参数,那么元素类型必须是 ABI 类型。
类型为 bytes 和 string 的变量是特殊数组。bytes 类似于 byte[],但它在 calldata 中被紧密地打包。因此,相比于 byte[],bytes 应该优先使用,因为更便宜。
字符串 string 等价于 bytes,但不允许长度或索引访问。
1. 声明数组
固定长度数组
声明一个固定长度的数组,需要指定元素类型和数量,如下所示:
type arrayName [ arraySize ];
这是一维数组。arraySize 必须是一个大于零的整数数字,type 可以是任何数据类型。
例如,声明一个 uint 类型,长度为10的数组:balance,如下所示:
uint balance[10];
动态数组
声明一个动态数组,只需要指定元素类型,无需指定数量,如下所示:
type arrayName [];
这是一维数组。arraySize 必须是一个大于零的整数数字,type 可以是任何数据类型。
例如,声明一个 uint 类型的动态数组:balance,如下所示:
uint balance[];
2. 初始化数组
初始化数组,可以使用下面的语句:
uint balance[3] = [1, 2, 3]; // 初始化固定长度数组 uint balance[] = [1, 2, 3]; // 初始化动态数组 balance[2] = 5; // 设置第 3 个元素的值为 5
3. 访问数组元素
可以通过索引访问数组元素。例如
uint salary = balance[2];
上面的语句将从数组中取出第 3 个元素,并将值赋给 salary 变量。
4. 动态数组和固定长度数据的区别
固定长度的数组在运行期间,是无法改变长度的。而动态数组可以改变。
动态数组可以使用 push 方法,在末尾追加一个元素;使用 pop 方法,截掉末尾元素。
两种数组的常用操作方法示例如下:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract SolidityTest { // 动态数组 uint[] public arr=[1,2,3,4]; // 固定长度数组 uint[4] public arrFixed=[1,2,3,4]; // 获得数组全部元素 function getArr() external view returns(uint[] memory) { return arr; } // 固定长度数组操作 function operatFixedArr() external { // 获得数组长度 //uint len = arrFixed.length; // len = 4 // 获得第二个元素 //uint x = arrFixed[1]; // x = 2 // 删除第二个元素,delete只将元素设置为初值,并不改变数组长度 delete arrFixed[1]; // [1,0,3,4] } // 动态数组操作 function operateDynamicArr() external { // 获得数组长度 //uint len = arr.length; // len = 4 // 追加一个元素 arr.push(5); // [1,2,3,4,5] // 弹出一个元素 arr.pop(); // [1,2,3,4] // 获得第二个元素 //uint x = arr[1]; // x = 2 // 删除第二个元素,delete只将元素设置为初值,并不改变数组长度 delete arr[1]; // [1,0,3,4] // 删除第二个元素,并且长度减1 removeAt(1); // [1,3,4] } // 删除数组元素,并且长度减1 function removeAt(uint i) public { require(i>=0 && i<arr.length); for (uint k=i; k<arr.length-1;k++){ arr[k] = arr[k+1]; } arr.pop(); } }
5. 创建内存数组
我们可以使用 new 关键字在内存中创建动态数组。内存动态数组的长度一旦确定,不能改变。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract SolidityTest{ function getMemoryArr() external pure returns(uint[] memory) { uint[] memory arr = new uint[](3); arr[0] = 1; return arr; } }
下一章:Solidity 结构体 struct
类似于C语言,solidity 也有结构体 struc 类型,用于表示复合型数据。结构体 struc 类型是引用类型。例如,一本书的信息:TitleAuthorBook IDOwner就可以用结构体来 ...