Solidity 引用类型(数组,结构,映射)详解(2023版)

数组

数组是数据类型,但更具体地说,它们是依赖于其他数据类型的数据结构。数组是指相同类型的数值组。数组有助于将这些值存储在一起,并简化迭代、排序和搜索该组中元素或子元素的过程。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;

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值