solidity引用类型中重要变量类型:数组(array)和结构体(struct)。
数组是用来存储一组数据(整数,字节,地址等等)。数组分为固定长度数组和可变长度数组两种:
固定长度数组:在声明时指定数组的长度。用x[k]的格式声明,其x是元素的类型,k是长度,例如:
// 固定长度 Array
uint[8] array1;
byte[5] array2;
address[100] array3;
可变长度数组:在声明时不指定数组的长度。用x[]的格式声明,其中x是元素的类型,例如(bytes比较特殊,是数组,但是不用加[])
// 可变长度 Array
uint[] array4;
byte[] array5;
address[] array6;
bytes array7;
创建数组的规则
在solidity里,创建数组有一些规则:
- 对于
memory
修饰的动态数组,可以用new
操作符来创建,但是必须声明长度,并且声明后长度不能改变。 - 数组字面常数是写作表达式形式的数组,并且不会立即赋值给变量,例如[uint(1),2,3](需要声明第一个元素的类型,不然默认用存储空间最小的类型)
- 如果创建的是动态数组,你需要一个一个元素的赋值。
uint[] memory x = new uint[](3); x[0] = 1; x[1] = 3; x[2] = 4;
1.length: 数组有一个包含元素数量的length成员,memory数组的长度在创建后是固定的。
2.push(x):动态数组和bytes拥有push()成员可以在数组最后添加一个x元素。
3.pop():动态数组和bytes拥有pop()成员可以在数组最后移除最后一个元素。
结构体struct
solidity支持通过构造结构体的形式定义新的类型。创建结构体的方法:
struct student{
uint id;
uint score;
}
(无论定义uint的大小,solidity都为它保留256位存储空间)
给结构体赋值的方法
// 方法1:在函数中创建一个storage的struct引用
function initStudent1() external{
Student storage _student = student;
_student.id = 18;
_student.score = 100;
}
// 方法2:直接引用状态变量的struct
function initStudent2() external{
student.id = 30;
student.score = 100;
}
映射是solidity中存储有组织数据的方法。映射本质上是存储和查找数据所用键-值对,格式是mapping(_KeyType => _ValueType)
mapping(uint => address) public idToAddress; // id映射到地址
mapping(address => address) public swapPair; // token对的映射,地址到地址
映射的规则
1.映射的_KeyType
只能选择solidity
默认的类型,比如uint
,address
等,不能用自定义的结构体。而_ValueType
可以使用自定义的类型。下面这个例子会报错,因为_KeyType
使用了我们自定义的结构体:
2.映射的存储位置必须是storage
,因此可以用于合约的状态变量,函数中的storage
变量。不能用于public
函数的参数或返回结果中,因为mapping
记录的是一种关系 (key - value pair)。
3.如果映射声明为public
,那么solidity
会自动给你创建一个getter
函数,可以通过Key
来查询对应的Value
。
4.给映射新增的键值对的语法为_Var[_Key] = _Value
,其中_Var
是映射变量名,_Key
和_Value
对应新增的键值对。
映射的原理
1.映射不储存任何键(Key
)的资讯,也没有length的资讯。
2.映射使用keccak256(key)
当成offset存取value。
3. 因为Ethereum会定义所有未使用的空间为0,所以未赋值(Value
)的键(Key
)初始值都是0。