数组是一种数据结构,它是存储同类元素的有序集合。
数组中的特定元素由索引访问,索引值从0开始。例如,声明一个数组变量,如numbers,可以使用numbers[0]、numbers[1]和…,数字[99]表示单个变量。
数组可以是固定大小的,也可以是动态长度的。
对于存储(storage
)数组,元素类型可以是任意的(可以是其他数组、映射或结构)。对于内存(memory
)数组,元素类型不能是映射类型,如果它是一个公共函数的参数,那么元素类型必须是ABI类型。
类型为bytes
和字符串的变量是特殊数组。bytes
类似于byte[]
,但它在calldata
中被紧密地打包。字符串等价于bytes
,但(目前)不允许长度或索引访问。
因此,相比于byte[]
,bytes
应该优先使用,因为更便宜。
声明数组
要声明一个固定长度的数组,需要指定元素类型和数量,如下所示
type arrayName [ arraySize ];
这是一维数组。arraySize
必须是一个大于零的整数数字,type
可以是任何数据类型。例如,声明一个uint
类型,长度为10的数组:balance
,如下所示:
uint balance[10];
初始化数组
初始化数组,可以使用下面的语句
uint balance[3] = [1, 2, 3];
可以省略数组长度:
uint balance[] = [1, 2, 3];
将创建与前一个示例完全相同的数组。
balance[2] = 5;
上面的语句,将数组中第3个元素赋值为5。
访问数组元素
可以通过索引访问数组元素。例如
uint salary = balance[2];
上面的语句将从数组中取出第三个元素,并将值赋给salary变量。
创建内存数组
可以使用new
关键字在内存中创建动态数组。与存储数组相反,不能通过设置.length
成员来调整内存动态数组的长度。
pragma solidity ^0.5.0;
contract C {
function f(uint len) {
uint[] memory a = new uint[](7);
bytes memory b = new bytes(len);
// a.length == 7, b.length == len
a[6] = 8;
}
}
数组成员
length
数组有一个length
成员来表示元素数量。动态数组可以通过更改.length
成员,在存储器(而不是内存)中调整大小。创建后,内存数组的大小是固定的(但是是动态的,长度可以是函数参数)。
push
动态存储数组和bytes
(不是字符串)有一个名为push的成员函数,可用于在数组末尾追加一个元素,函数返回新的长度。
pragma solidity ^0.4.0;
contract ArrayContract {
uint[2**20] m_aLotOfIntegers;
bool[2][] m_pairsOfFlags;
// newpair存储在内存中——这是函数参数的默认存储位置
function setAllFlagPairs(bool[2][] newPairs) {
// 对存储数组赋值,替换传入的整个数组
m_pairsOfFlags = newPairs;
}
function setFlagPair(uint index, bool flagA, bool flagB) {
// 访问不存在的索引将引发异常
m_pairsOfFlags[index][0] = flagA;
m_pairsOfFlags[index][1] = flagB;
}
function changeFlagArraySize(uint newSize) {
// 如果newSize更小,则删除的数组元素将被清除
m_pairsOfFlags.length = newSize;
}
function clear() {
// 完全清除数组
delete m_pairsOfFlags;
delete m_aLotOfIntegers;
// 效果相同
m_pairsOfFlags.length = 0;
}
bytes m_byteData;
function byteArrays(bytes data) {
// byte 数组 ("bytes") 存储时没有填充(padding),
// 但是可以与“uint8[]”相同处理
m_byteData = data;
m_byteData.length += 7;
m_byteData[3] = 8;
delete m_byteData[2];
}
function addFlag(bool[2] flag) returns (uint) {
return m_pairsOfFlags.push(flag);
}
function createMemoryArray(uint size) returns (bytes) {
// 使用“new”创建动态内存数组:
uint[2][] memory arrayOfPairs = new uint[2][](size);
// 创建一个动态byte数组:
bytes memory b = new bytes(200);
for (uint i = 0; i < b.length; i++)
b[i] = byte(i);
return b;
}
}