前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Solidity:常用数据结构

Solidity:常用数据结构

作者头像
孟斯特
发布2024-05-28 20:39:22
940
发布2024-05-28 20:39:22
举报
文章被收录于专栏:code人生code人生

在 Solidity 中,有各种各样的数据结构可用于组织和处理信息。以下是一些最常用的数据结构。

1. Array

在 Solidity 中,数组(Array)是一种基础的数据结构,它能存储同一类型的多个元素,元素在数组里的顺序由其索引值决定。根据所定义的长度,数组可以分为两种类型:定长动态。确定长度的数组在创建时固定其大小,之后就不能再改变;动态数组则没有固定的长度,可以添加或删除元素。

创建数组

静态数组的创建方式如下,其中 <Type> 是元素的数据类型,<Size> 是数组长度:

代码语言:javascript
复制
<Type>[<Size>] arrayName;

例如,创建一个长度为5且元素类型为uint的数组,可以如下创建:

代码语言:javascript
复制
uint[5] myArray;

对于动态数组,其创建方式如下:

代码语言:javascript
复制
<Type>[] arrayName;

例如,创建一个动态数组,元素类型为uint

代码语言:javascript
复制
uint[] myArray;

访问和修改数组中元素

在 Solidity 中,使用数组的索引(从0开始)可以访问或修改数组中的元素。例如:

代码语言:javascript
复制
myArray[0] = 10;  // 修改数组中第一个元素的值为10
uint firstElement = myArray[0];  // 访问数组中的第一个元素

数组的属性和方法

对于数组,有以下一些常用的属性和方法:

length属性:返回数组的长度。•push方法:只适用于动态数组,用于在数组的末尾添加一个元素,同时数组的长度会增加1。•pop方法:只适用于动态数组,用于删除数组的最后一个元素,同时数组的长度会减少1。

下面的示例中展示了如何在 Solidity 中使用动态数组:

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract Test {
    uint[] public numArray;

    // 添加元素到数组中
    function addToArray(uint num) public {
        numArray.push(num);
    }

    // 获取数组的长度
    function getArrayLength() public view returns (uint) {
        return numArray.length;
    }

    // 根据索引获取数组中的元素
    function getElement(uint index) public view returns (uint) {
        return numArray[index];
    }

    // 移除数组的最后一个元素
    function removeLastElement() public {
        numArray.pop();
    }
}

2. Struct

在Solidity中,结构体(Struct)是一种复杂的数据类型,允许你组合多个不同类型的变量到一个单独的实体。

创建一个结构体的基本语法如下:

代码语言:javascript
复制
struct StructName {
    Type1 variable1;
    Type2 variable2;
    ...
}

其中,“StructName”是你为结构体定义的名字,“Type1”和“Type2”是变量的数据类型(例如 uint、address、string等), “variable1”和“variable2”是这些变量的名字。

以下是一个具体的结构体定义示例:

代码语言:javascript
复制
struct Student {
    uint id;
    string name;
    uint age;
}

在定义了结构体之后,你可以创建一个新的结构体实例,并初始化其值。例如:

代码语言:javascript
复制
Student memory newStudent = Student({
    id: 1,
    name: "Alice",
    age: 20
});

注意,在上面的代码块中,“memory”关键字是必需的,表示这个结构体实例是存在于内存中的。

你还可以直接访问和修改结构体的成员变量。例如:

代码语言:javascript
复制
newStudent.name = "Bob";  // 修改结构体实例中的"name"字段
string studentName = newStudent.name;  // 访问结构体实例中的"name"字段

另外,你还可以将结构体存储在数组或者映射中,以实现更复杂的数据管理。例如:

代码语言:javascript
复制
// 存储在数组中
Student[] public students;

// 存储在映射中,其中地址是键,Student结构体为值
mapping(address => Student) public studentInfo;

下面的示例展示了 Struct 的简单使用场景:

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract StructExample {
    struct Student {
        uint256 id;
        string name;
        uint256 age;
    }

    Student[] public students;

    function addStudent(
        uint256 _id,
        string calldata _name,
        uint256 _age
    ) public {
        // 3种初始化方式
        // 1. 像调用函数一样,初始化时形参的顺序需与结构体字段顺序一致
        students.push(Student(_id, _name, _age));

        // // 2. key => value形式
        // students.push(Student({id: _id, name: _name, age: _age}));

        // // 3. 使用临时变量
        // Student memory stu;
        // stu.age = _age;
        // stu.id = _id;
        // stu.name = _name;
        // students.push(stu);
    }

    function getStudent(uint256 _index)
        public
        view
        returns (
            uint256,
            string memory,
            uint256
        )
    {
        Student memory stu = students[_index];
        return (stu.id, stu.name, stu.age);
    }
}

3. Mapping

在 Solidity 中,映射(mapping)是一种关联一个类型的值(键)到另一个类型的值(值)的数据结构,它类似于许多编程语言中的哈希表或字典。映射的键的类型可以是任何基本类型,包括字节和整数类型,但不能是映射、动态数组、合约、枚举和结构。映射的值的类型则几乎没有任何限制,甚至可以是另一个映射。

以下是创建一个映射的基本语法:

代码语言:javascript
复制
mapping(_KeyType => _ValueType) public mappingName;

在这里,_KeyType是键的数据类型,_ValueType是值的数据类型,并且public关键词使得映射可以被合约以外的程序读取(但无法修改)。

举个例子,以下代码创建了一个名为balances的映射,它将地址映射到uint值:

代码语言:javascript
复制
mapping(address => uint) public balances;

在创建了映射之后,可以使用中括号[]来访问或修改映射中的元素,

代码语言:javascript
复制
balances[address1] = 100;  // 设置地址address1 的余额为100 
uint balance = balances[address1];  // 获取地址address1 的余额

需要注意的是,映射在默认情况下所有键都存在且对应的值默认为类型的初始值,如对应uint的默认是0,对应bool的默认为false

以下是一个更完整的使用映射管理账户余额的 Solidity 合约示例:

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract MyContract {
    // 定义一个映射,用来存储每个地址对应的余额
    mapping(address => uint) public balances;

    // 存款
    function deposit(uint amount) public {
        // 增加发送者的余额
        balances[msg.sender] += amount;
    }

    // 获取余额
    function getBalance() public view returns (uint) {
        return balances[msg.sender];
    }
}

4. Enum

在Solidity中,枚举类型(enum)是由开发者定义的一种特殊类型,它允许你创建一组预定义的值。枚举可以被看作是一种限制了值的类型,这有助于使代码更加清晰易懂,减少错误。

以下是定义一个枚举类型的基本语法:

代码语言:javascript
复制
enum EnumName {
    Value1,
    Value2,
    ...
}

在这里,“EnumName”是你为枚举定义的名字,“Value1”和“Value2”等则是枚举中的值。

以下是一个实际的枚举定义示例:

代码语言:javascript
复制
enum State {
    Created,
    Locked,
    Inactive
}

在此例中,State 是枚举的名字,而 CreatedLockedInactive 则是该枚举中的值。

一旦定义了一个枚举类型,就可以在合约中创建该类型的变量,并将其设置为该枚举中的值。例如:

代码语言:javascript
复制
State public state = State.Created;

在上面的代码段中,有一个公开的 State 类型的状态变量,它的初始值被设置为Created

你还可以在合约的函数中修改或检查这个枚举类型的变量:

代码语言:javascript
复制
function makeInactive() public {
    state = State.Inactive;  // 修改枚举变量的值
}

function checkState() public view returns(bool) {
    return state == State.Inactive;  // 检查枚举变量的值
}

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)[1]进行许可,使用时请注明出处。 Author: mengbin[2] blog: mengbin[3] Github: mengbin92[4] cnblogs: 恋水无意[5] 腾讯云开发者社区:孟斯特[6]

References

[1] 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0): https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh [2] mengbin: mengbin1992@outlook.com [3] mengbin: https://mengbin.top [4] mengbin92: https://mengbin92.github.io/ [5] 恋水无意: https://www.cnblogs.com/lianshuiwuyi/ [6] 孟斯特: https://cloud.tencent.com/developer/user/6649301

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 孟斯特 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Array
  • 2. Struct
  • 3. Mapping
  • 4. Enum
    • References
    相关产品与服务
    对象存储
    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档