数组
数组是数据类型,但更具体地说,它们是依赖于其他数据类型的数据结构。数组是指相同类型的数值组。数组有助于将这些值存储在一起,并简化迭代、排序和搜索该组中元素或子元素的过程。Solidity 提供了丰富的数组结构,可以满足不同的需求。
固定数组(定长数组)
固定数组是指声明了预定大小的数组。固定数组的例子如下:
int[5] age;
byte[4] flags;
固定数组无法使用new关键字进行初始化。它们只能以内联方式初始化,如下面的代码所示:
int[5] age = [1,2,3,4,5];
它们也可以稍后在函数中内联初始化,如下所示:
int[5] age;
age = [1,2,3,4,5];
动态数组
length表示数量,push推入
动态数组是指在声明时没有预定大小的数组,但是,它们的大小是在运行时确定的。代码如下:
int[] age;
byte[] flags;
动态数组可以内联初始化,可以在声明时初始化,如下所示:
int[] age = [1,2,3,4,5];
可以通过push来后输入数据
ages.push(_age);
通过length来查看数组长度
ages.length;
特殊数组
Solidity 提供了以下两个特殊数组:
- 字节数组
- 字符串数组
字节数组
字节数组是一个动态数组,可以容纳任意数量的字节。它与byte[]不同。byte[] 数组每个元素占用32个字节,而字节数组紧紧地将所有字节保存在一起。
字节可以声明为具有初始长度大小的状态变量,如以下代码所示:
bytes localBytes = new bytes(0);
这也可以分成与以前讨论的数组类似的以下两条代码行:
bytes localBytes;
localBytes = new bytes(10);
字节数组可以直接赋值,如下所示:
localBytes = "solidity is good";
此外,如果数据位于存储位置,则可以将值压栈其中,如下面的代码所示:
localBytes.push(byte(10));
字节数组还提供读/写长度属性,如下所示:
return localBytes.length;
localBytes.length = 4;
字符串数组
字符串是基于上一节讨论的字节数组的动态数据类型。它们与附加约束的字节数组非常相似。字符串不能被索引或压栈,也不具有 length 属性。要对字符串变量执行任何这些操作,应首先将其转换为字节,然后在操作后将其转换回字符串。
字符串可以由单引号或双引号内的字符组成。字符串可以直接声明并赋值,如下所示:
String name = "mike";
它们也可以转换为字节,如下所示:
Bytes byteName = bytes(name);
映射(mapping)
映射是 Solidity 中最常用的复杂数据类型之一。映射类似于其他语言中的散列表或字典。它们存储键值对,并允许根据提供的键来检索值。
使用 mapping 关键字声明映射,后跟由=>表示法分隔的键和值的数据类型。映射具有与任何其他数据类型一样的标识符,并且它们可用于访问映射。
一个声明映射的例子如下:
mapping(uint => address) public Names;
在前面的代码中,uint 数据类型用于存储键而 address 数据类型用于存储值。Names 用作映射的标识符。
虽然它类似于散列表和字典,但 Solidity 不允许迭代映射。如果键已知,则可以检索映射中的值。下一个示例说明如何使用映射。合约中维护有一个 uint 类型的计数器作为映射的键,并且在函数的帮助下存储和检索地址详细信息。
要访问映射中的任何特定值,相关键应与映射名一起使用,如下所示:
Names[uint(3)];
要在映射中存储值,请使用以下语法:
Names[uint(4)] = 0xc6a115f2abc09746963d6a6800bd82157d27d8e7
下面是一个完整的示例:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0;
contract MapTest{
mapping(address =>uint) idmapping;
mapping(uint =>string) namemapping;
uint public sum=0;
function register(string memory name)public{
address account =msg.sender;
sum++;
idmapping[account]=sum;
namemapping[sum]=name;
}
function getIdByAddress(address add)view public returns(uint){
return idmapping[add];
}
function getNameById(uint id)view public returns(string memory){
return namemapping[id];
}
}
结构
结构或结构体有助于实现自定义的用户数据类型。结构是一种复合数据类型,由多个不同数据类型的变量组成。它们与合约非常相似,但是,它们不包含任何代码。它们只包含变量。
Solidity 的结构中的 struct 关键字进行声明。结构中的变量在花括号{}内定义,如图所示:
struct user {
string name;
uint age;
int id;
address addr;
}
使用下面的语法来创建一个结构的实例。不需要显式调用关键字 new。关键字new只用于创建合约或者数组的实例,如图所示:
student = user("LiMing", 23, 1, 0xc6a115f2abc09746963d6a6800bd82157d27d8e7);
下面是一个完整示例:
contract struct_demo{
User user;
struct User{
string name;
uint8 age;
string sex;
}
function setUser(string memory _name,uint8 _age,string memory _sex)public{
user.name=_name;
user.age=_age;
user.sex=_sex;
}
function getUser()public view returns(User memory){
return user;
}
}