あなたもきっと、誰かの奇跡 (你也一定会是某个人的奇迹)

目录

一、Solidity的结构体

1.结构体的实例化

2.结构体的基本使用

访问和修改结构体成员

3.结构体的修饰符

二、Solidity的映射

1.映射的基本使用

查询和修改某个value值

三、Solidity的枚举

四、数组、结构体、映射的直接相互嵌套

1.没有数组嵌套数组

2.数组嵌套结构体

3.没有数组嵌套映射

4.结构体嵌套数组

5.结构体嵌套结构体

6.结构体嵌套映射

7.映射嵌套数组

8.映射嵌套结构体

9.映射嵌套映射

10、重要说明(间接嵌套)

五、关于枚举的嵌套


一、Solidity的结构体

结构体是一个引用数据类型,用于表示复合型数据

在结构体里面的数据我们称之为成员

结构体可以任何数据类型作为体内的成员,但是不能内部包含自身结构体,也就是不能在自己的结构体中写自己的结构体

结构体可以多次实例化,且各个实例化互不影响

关键字:struct

 

定义结构体格式:

struct 结构体名 {

成员1;

成员2;

成员3;

```````````

}

结构体的可见性:

关于可见性,目前只支持internal,所以结构体只能在合约内部和子合约内使用。包含结构体的函数必须显性声明为internal

因此结构体里面的成员也是internal,不能再定义权限修饰符了

1.结构体的实例化

结构体创建后其实是一个模板类似于java中的类,对其实例化以后,相当于拿了这个模板去使用,同一个结构体不同实例化互不影响,自己存储在自己对应的实例化内存中,类似于java的对象

实例化格式:

结构体名  修饰符 实例化结构体名

温馨提示:结构体实例化之后,会给实例化结构体内部数据赋予一个初始值

结构体实例化后整体赋值:

实例化名 = 结构体名(值1,值2,·····)

注意:上下这两种方式是整体赋值必须全部赋值,否则报错

实例化结构体并初始化格式:

结构体名 修饰符 实例化名 = 结构体名(值1,值2,·····)    这个要按成员顺序赋值

结构体名 修饰符 实例化名 = 结构体名({ 成员:值,成员:值,···})   这个可以不按照顺序赋值

2.结构体的基本使用

访问和修改结构体成员

访问结构体成员格式:

实例化结构体名.成员

修改结构体成员格式:

实例化结构体名.成员 = 新值

3.结构体的修饰符

结构体实例化的修饰符是用于修饰它所存储的位置用memory/storage或者方位权限public````等

如果在函数外实例化,默认强制存储storage不需要写修饰符

如果在函数内实例化,就必须写所存储的位置

当结构体中存在mapping时,不允许再用memory创建和初始化,要用storage(因为maaping只能存储在storage中)

结构体中的mapping类型,可初始化,也可不初始化,其他类型不可

要对结构体中的mapping操作,只能通过storage的存储来操作

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract test {struct Student {string name;int age;}Student public stu;function set() public returns(string memory,int){stu = Student(unicode'大哥',2);stu.age=100;return (stu.name,stu.age);//大哥,100}}

二、Solidity的映射

映射 mapping 是智能合约中很常用的一种数据类型,它是引用类型。

Solidity 映射 mapping 用于以键值对的形式存储数据

键 = key   值 = value

一个key对应者一个value

它与使用结构体不同,和数组类似,创建后不需要实例化,直接使用

  • 在mapping中key可以是整型、字符串等基本数据类型,但不是引用数据类型和枚举
  • 而value的类型没有数据类型限制,可以是任意数据类型,甚至使用一个mapping作为value也是允许的,

温馨提示:mapping不能作为参数使用,也不能返回整个mapping,只能返回key对应的value

关键字: mapping

映射的定义格式:

mapping(key数据类型 => value数据类型) 权限修饰符 映射名

注意

  • 映射的数据位置只能是 storage,通常用于状态变量。所以它不可以定义存储修饰符
  • 映射可以标记权限修饰符,当权限修饰符为 public, Solidity 会创建一个 getter 函数。 key数据 将成为 getter 的必须参数,并且 getter 会返回 key数据对应的value

映射是没有长度的,也没有 key 的集合或 value 的集合的概念。映射只能是存储的数据位置,因此只允许作为状态变量或作为函数内的存储引用 或 作为库函数的参数。 它们不能用于合约公有函数的参数或返回值。

1.映射的基本使用

查询和修改某个value值

在映射中我们只能查询到value的值,查询不到key的值,也就是说可以通过key查询value但不能通过value查询key

查询value格式:

映射名[key值]

修改value格式:

映射名[key值] = 新value值

初始化映射(删除)

delete 映射名[key值]

注意事项:在映射的查询中,如果赋予一个不存在(没有存储)的key值,那么它所对应和返回的value值就是value数据类型的默认值

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract test {mapping(int=>int) public a;function set() public returns(int){a[1]=2;return a[1];}function tests(int _b) public view returns(int){return a[_b];}}

三、Solidity的枚举

solidity 的枚举类型 是一种用户自定义类型,用于表示多种状态。

枚举类型内部就是一个自定义的整型,默认的类型为uint8,当枚举数足够多时,它会自动变成uint16。(也就是枚举里面存放的元素个数)

枚举类型可以与整数进行显式转换,但不能进行隐式转换。显示转换会在运行时检查数值范围,如果不匹配,将会引起异常。

关键字:enum 

 

定义格式:

enum 枚举名 {     枚举元素1,枚举元素2,枚举元素3,·····    }

注意,枚举的结尾}不需要加;

定义枚举类型变量:

枚举名 权限修饰符 枚举变量名

枚举类型的变量用于存放枚举里面的某个元素值,默认的值为第一个枚举元素值

给枚举变量赋值:

第一种:枚举内元素赋值

枚举变量名 = 枚举名.枚举元素

第二种:自定义uint类型数据赋值

枚举变量名 = uint类型数据

注意:所给枚举变量赋值的uint类型数据必须是枚举元素内含有的值(枚举元素1-枚举元素n的uint值范围)不是该范围则运行报错

重置枚举变量:将其重置为枚举元素1的值

关键字:delete

格式:

delete 枚举变量名

枚举体语法格式注释:
1)enum必须要有成员对象, { }中不能为空;
2)enum 中不能出现中文;
3){ }中不能加分号

使用枚举类型的主要好处:

  • 明确值的范围,防止错误的值输入。

  • 提高代码的可读性,使得代码更加清晰易懂。

  • 便于维护,需要增加/删除枚举类型的值的时候,只需要修改枚举类型的定义,不需要修改使用枚举类型的代码。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract EnumExample {enum Status {Pending,Shipped,Accepted,Rejected,Canceled//枚举类型是unit8数据结构,内部元素均为uint8由0开始按顺序赋值//若元素超出了uint8赋值则增加为uint16// 枚举元素   对应的uint// Pending  --- 0// Shipped  --- 1// Accepted --- 2// Rejected --- 3// Canceled --- 4}//定义了枚举类型的变量Status public status; function get() public view returns (Status) {return status;  //默认分配Pending 0}function set1() public {status = Status.Canceled; //设置枚举元素Canceled 4}function set(Status _a) public {status = _a; //外部uint值类型  范围  0-4  ,不是该范围则运行报错}function reset() public {delete status;}
}

四、数组、结构体、映射的直接相互嵌套

1.没有数组嵌套数组

数组不能嵌套数组,只能数组和数组之间相互赋值

2.数组嵌套结构体

在数组里面存放结构体,我们称之为数组结构体

定义格式:

结构体名[长度] 修饰符 数组名

提示:长度可写可不写,写了代表定长数组,不写代表变长数组,变长数组要注意一开始没有长度,需要push()添加值(变长)

查询一个下标对应整个结构体格式:

数组名[下标]

查询一个下标对应结构体的成员值格式:

数组名[下标].结构体成员名

赋值就在查询后面加个 =

作为函数参数的注意事项

当返回的是一个数组结构体值,那么返回的参数也必须是数组结构体

当数组结构体作为形参,那么传入的实参也必须是数组结构体

3.没有数组嵌套映射

数组不能嵌套映射,只能数组和映射相互赋值

4.结构体嵌套数组

在结构体里面让数组作为结构体成员,我们称之为结构体数组

结构体数组可以是变长的也可以是定长的

结构体数组定义格式:

struct 结构体名 {

数据类型[长度] 权限修饰符 数组名;

}

无法给结构体数组初始化赋值

 

访问结构体数组:

实例化结构体名.数组名

访问结构体数组的数组元素

实例化结构体名.数组名[下标]

给某个实例化结构体中的映射赋值

实例化结构体名.数组名[下标] = 元素值

如果是变长数组则是push()赋值

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Example {struct  aaa {string name;int age;int[2] arr;int[] arr2;}aaa public a;function set() public {a.name=unicode'a';a.age=19;a.arr[0]=123;a.arr2.push(10);}function get() public view returns(int,int){return(a.arr[0],a.arr2[0]);}function getArr() public view returns(int[2] memory){return a.arr;}}   

5.结构体嵌套结构体

结构体嵌套结构体,我们称之为结构体结构体,嵌套的里面的结构体是实例化的结构体

结构体结构体定义格式:

struct 结构体名1 {

成员;

·····

}

struct 结构体名 {

实例化结构体1

}

访问结构体结构体:

实例化结构体名.实例化结构体1

访问结构体数组的数组元素

实例化结构体名.实例化结构体1.实例化结构体1的成员

赋值就后面加 =

6.结构体嵌套映射

在结构体里面嵌套映射作为结构体的成员,我们成之为结构体映射

注意事项:

  • 当结构体中存在mapping时,不允许再用memory对结构体实例化,要用storage(因为maaping只能存储在storage中)
  • 要对结构体中的mapping操作,只能通过storage的存储来操作
  • 在结构体里面的映射不能加权限修饰符,它强制和struct一样的权限

 

结构体映射定义格式:

struct 结构体名 {

mapping(key类型 => value类型) 映射名;

}

对结构体实例化并初始化mapping

以大括号引出,不按顺序赋值结构体名  别名= 结构体名(  { key名:值,value名:值  }  )

实例化结构体后对mapping初始化

以大括号引出,按顺序赋值结构体名:  实例化= 结构体名(    { key值,value值    }   )

访问结构体种的映射value值

实例化结构体名.映射名[kye值]

给某个实例化结构体中的映射赋值

实例化结构体名.映射名[key值] = value值

作为函数参数的注意事项

当返回的是一个数组结构映射,那么返回的参数也必须是结构体映射

当结构体映射作为形参,那么传入的实参也必须是结构体

7.映射嵌套数组

映射内的value作为数组,整个数组被映射嵌套,我们称之为映射数组

定义格式:

mapping(key类型 => 数组类型[长度]) 权限修饰符 映射名

访问映射里面存储数组

映射名[key值]

访问映射里面存储的数组具体值

映射名[key值][下标]

赋值就在查询后面加个 =

注意事项:映射本身固定为storage类型,因此使用的数组也必须是storage类型

如果里面是动态数组,则需要使用push()来赋值,格式:

映射名[key值].push(值)

8.映射嵌套结构体

映射内的value作为结构体,整个结构体被映射嵌套,我们称之为映射结构体

定义格式:

mapping(key类型 => 结构体名) 权限修饰符 映射名

访问映射里面存储的某个实例化结构体

映射名[key值]

访问映射里面存储的某个实例化结构体成员

映射名[key值].结构体成员

赋值就在查询后面加个 =

注意事项:映射本身固定为storage类型,因此使用的结构体也必须是storage类型

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Example {struct aaa {string name;int age;}mapping(int=>aaa) public bbb;aaa public a;function get(string memory _name,int _age,int _id) public returns(aaa memory,int) {a.name=_name;a.age=_age;bbb[_id]=a;return (bbb[_id],bbb[_id].age);}}

9.映射嵌套映射

映射内的value作为映射,整个内部映射被外部映射嵌套,我们称之为映射映射

定义格式:

mapping(key类型 => mapping(key类型=>value类型)) 权限修饰符 映射名l

例如

mapping(int=>mapping(int=>string)) public a;

访问映射里面存储的映射

映射名[外部key值]

访问映射里面存储的映射的value值

映射名[外部key值][内部key值]

赋值就在查询后面加个 =

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SolidityTest {mapping(int=>mapping(int=>string)) public a;function tran() public returns(string memory) { a[1][2]='a';a[1];return a[1][2];}
}

10、重要说明(间接嵌套)

虽然有些不能直接嵌套,但是可以通过结构体作为媒介进行间接嵌套

而结构体可以通过数组和映射作为媒介间接嵌套

当然有些能直接前嵌套也能间接嵌套

例如

数组-->结构体-->数组

映射-->结构体-->映射

映射--结构体-->数组

数组--结构体-->映射

结构体 -->数组 -->结构体

结构体 -->映射 --> 结构体

五、关于枚举的嵌套

枚举通常都是作为枚举变量使用

枚举只能以枚举变量的形式嵌套在结构体内

使用枚举变量的注意事项:

1.枚举变量的赋值只能给枚举类型变量赋值,或枚举元素

2.枚举变量不能存放到数组、结构体、映射、普通变量中去,因为数据类型不一样

3.枚举变量可以定义到结构体里面,然后对结构体内的枚举变量赋予枚举变量(间接性)

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract Enum{enum Status {None,Padding,Shipped,Completed,Rejected,Canceled}Status public status;//枚举变量struct Order {address buyer;Status status;//结构体嵌套枚举}Order[] public orders;//数组结构体function get() view external returns (Status) {return status;//返回枚举变量}function set(Status _status) external  {status = _status;//枚举变量的赋值}function ship() external {status = Status.Shipped;//枚举变量的赋值}function reset() external{delete status;//重置枚举变量}
}

Solidity基础四相关推荐

  1. Solidity 基础知识

    Solidity 基础知识 官网:Solidity 版本设置 // SPDX-License-Identifier:MIT 表示身份协议 // ^0.8.7 表示当前代码支持 0.8.7 及以后 so ...

  2. 智能车竞赛技术报告 | 基础四轮组 - 哈尔滨工程大学 - 济海追风5队

    简 介: 本文详细介绍了哈尔滨工程大学"济海追风5队"在第十六届全国大学生智能汽车竞赛基础四轮组中的系统方案.本次比赛采用大赛组委会指定的B3型车模,以英飞凌半导体公司生产的32位 ...

  3. mysql 连接 分组_MySQL 基础 (四) 分组查询及连接查询

    MySQL 基础 (四) 分组查询及连接查询 MySQL 基础(四) 进阶 5 分组查询 语法: SELECT 分组函数, 列(要求出现在 group by 的后面) FROM 表 [where 筛选 ...

  4. 【RabbitMQ】基础四:路由模式(Routing)

    [RabbitMQ]基础四:路由模式(Routing) 1. 路由模式说明 2. 代码示例 2.1 生产者 2.2 消费者1 2.3 消费者2 2.4 测试 3. 总结 1. 路由模式说明 路由模式特 ...

  5. [GO语言基础] 四.算术运算、逻辑运算、赋值运算、位运算及编程练习

    作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.前文介绍了Golang的 ...

  6. 计算机科学与技术学习路线编程基础四大件应用实践编程(含C++学习路线)

    计算机科学与技术学习路线&编程基础四大件&应用实践编程(含C++学习路线) 基本介绍 本人211科班出身,目前大学临近毕业,想给迷茫的同行者或者后来人一些建议和推荐,少走弯路.想想自己 ...

  7. 第十五届全国大学生智能汽车竞赛 基础四轮组总结

    第十五届全国大学生智能汽车竞赛 基础四轮组总结 一.方案 循迹:纯电磁 硬件 比赛过程 二.总结 一.方案 1.车模:C1 2.主控:RT1064 3.传感器:电磁循迹.红外对管+干簧管识别斑马线 循 ...

  8. 《计算机应用基础》第四次作业,[业务]计算机应用基础四次小作业

    [业务]计算机应用基础四次小作业 (8页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 本科专业第一次小作业辅导:课本第39页,第52页的填空 ...

  9. 17届智能车竞赛技术报告 | 乐师逐飞二队 - 基础四轮组

    学 校:乐山师范学院       队伍名称:乐师逐飞二队     参赛队员:唐冰奇 罗文祝 唐玉琴 带队教师:杨济豪 李富钢     简 介: 本文以第十七届全国大学生智能车竞赛为背景,以大赛组委会指 ...

最新文章

  1. efcore多表查询出错_如何提高sql查询的效率?
  2. Reason not to use LINQ and reason to use
  3. 用python让excel飞起来 pdf_老外用100个巨型吹风机, 想要靠它们飞起来, 你猜结果怎样...
  4. 从零开始学Xamarin.Forms(四) Android 准备步骤(添加第三方Xamarin.Forms.Labs库)
  5. 每天五分钟,玩转Docker。-Day2
  6. 【Pytorch神经网络理论篇】 02 Pytorch快速上手(二)GPU与CPU张量切换+具有随机值的张量+张量的数学运算
  7. Django与jQuery通信;Django前后端传值
  8. How to include library manually into maven local repository?
  9. Java Singleton类中的线程安全性的示例代码
  10. 线性查找法java代码_Java线性查找和二分查找
  11. 人工智能/数据科学比赛汇总 2019.3
  12. 李国庆夺章后“发配”俞渝,当当网上线“从摔杯到抢章”专题,书目亮了
  13. 湖南第一师范计算机科学与技,湖南第一师范学院2019年各省各专业录取分数线...
  14. nlp基础—9.条件随机场模型(CRF算法)
  15. docker server 容器连接sql_借力 Docker ,三分钟搞定 MySQL 主从复制!
  16. 推荐一个下载简历模板的网站工具
  17. 地址后面的sessionid怎么消除_富贵包的消除和改善头前倾,通过运动和减肥可以吗?...
  18. 阿里云Centos8 yum报错Failed to synchronize cache for repo ‘BaseOS‘解决方案,通过换文件的方式来解决。
  19. 数字IC验证方法的分类
  20. 社群运营怎么做更有效?

热门文章

  1. java 计算两个时间之间的间隔
  2. 【Dart 教程系列第 49 篇】Dart 是值传递还是引用传递
  3. EXCEL将默认单元格格式修改成常规
  4. Encoder-Decoder -编码器解码器架构(RNN循环神经网络)
  5. android build.gradle在哪里,android中的build.gradle是干什么用的
  6. 计算机毕业设计php+vue基于微信小程序的贵小团校园社团小程序
  7. 简单理解CMS与G1垃圾收集器
  8. UNIX操作系统族谱 —— 发展脉络一览
  9. SqlServer数据库删除数据
  10. Python-turtle绘画旅程第一站:哆啦a梦