Solidity: 引用类型, array, struct

数组 array​

数组(Array)是Solidity常用的一种变量类型,用来存储一组数据(整数,字节,地址等等)。数组分为固定长度数组和可变长度数组两种:

  • 固定长度数组:在声明时指定数组的长度。用T[k]的格式声明,其中T是元素的类型,k是长度,例如:

    // 固定长度 Array
    uint[8] array1;
    bytes1[5] array2;
    address[100] array3;
    
  • 可变长度数组(动态数组):在声明时不指定数组的长度。用T[]的格式声明,其中T是元素的类型,例如:

    // 可变长度 Array
    uint[] array4;
    bytes1[] array5;
    address[] array6;
    bytes array7;
    

    注意bytes比较特殊,是数组,但是不用加[]。另外,不能用byte[]声明单字节数组,可以使用bytesbytes1[]bytes 比 bytes1[] 省gas。

创建数组的规则​

在Solidity里,创建数组有一些规则:

  • 对于memory修饰的动态数组,可以用new操作符来创建,但是必须声明长度,并且声明后长度不能改变。例子:

    // memory动态数组
    uint[] memory array8 = new uint[](5);
    bytes memory array9 = new bytes(9);
    
  • 数组字面常数(Array Literals)是写作表达式形式的数组,用方括号包着来初始化array的一种方式,并且里面每一个元素的type是以第一个元素为准的,例如[1,2,3]里面所有的元素都是uint8类型,因为在Solidity中,如果一个值没有指定type的话,会根据上下文推断出元素的类型,默认就是最小单位的type,这里默认最小单位类型是uint8[uint(1),2,3]里面的元素都是uint类型,因为第一个元素指定了是uint类型了,里面每一个元素的type都以第一个元素为准。

    下面的例子中,如果没有对传入 g() 函数的数组进行 uint 转换,是会报错的。

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.4.16 <0.9.0;
    
    contract C {
        function f() public pure {
            g([uint(1), 2, 3]);
        }
        function g(uint[3] memory _data) public pure {
            // ...
        }
    }
    
  • 如果创建的是动态数组,你需要一个一个元素的赋值。

    uint[] memory x = new uint[](3);
    x[0] = 1;
    x[1] = 3;
    x[2] = 4;

 

数组成员​

  • length: 数组有一个包含元素数量的length成员,memory数组的长度在创建后是固定的。
  • push()动态数组拥有push()成员,可以在数组最后添加一个0元素,并返回该元素的引用。
  • push(x)动态数组拥有push(x)成员,可以在数组最后添加一个x元素。
  • pop()动态数组拥有pop()成员,可以移除数组最后一个元素。

结构体 struct​

Solidity支持通过构造结构体的形式定义新的类型。结构体中的元素可以是原始类型,也可以是引用类型;结构体可以作为数组或映射的元素。创建结构体的方法:

// 结构体
struct Student{
    uint256 id;
    uint256 score; 
}

Student student; // 初始一个student结构体

给结构体赋值的四种方法:

//  给结构体赋值
// 方法1:在函数中创建一个storage的struct引用
function initStudent1() external{
    Student storage _student = student; // assign a copy of student
    _student.id = 11;
    _student.score = 100;
}
// 方法2:直接引用状态变量的struct
function initStudent2() external{
    student.id = 1;
    student.score = 80;
}
// 方法3:构造函数式
function initStudent3() external {
    student = Student(3, 90);
}
// 方法4:key value
function initStudent4() external {
    student = Student({id: 4, score: 60});
}


测试代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
contract ArrayTypes {

    // 固定长度 Array
    uint[8] array1;
    bytes1[5] array2;
    address[100] array3;

    // 可变长度 Array
    uint[] array4;
    bytes1[] array5;
    address[] array6;
    bytes array7;

    // 初始化可变长度 Array
    uint[] array8 = new uint[](5);
    bytes array9 = new bytes(9);
    //  给可变长度数组赋值
    function initArray() external pure returns(uint[] memory){
        uint[] memory x = new uint[](3);
        x[0] = 1;
        x[1] = 3;
        x[2] = 4;
        return(x);
    }  
    function arrayPush() public returns(uint[] memory){
        uint[2] memory a = [uint(1),2];
        array4 = a;
        array4.push(3);
        return array4;
    }
}

pragma solidity ^0.8.21;
contract StructTypes {
    // 结构体 Struct
    struct Student{
        uint256 id;
        uint256 score; 
    }
    Student student; // 初始一个student结构体
    //  给结构体赋值
    // 方法1:在函数中创建一个storage的struct引用
    function initStudent1() external{
        Student storage _student = student; // assign a copy of student
        _student.id = 11;
        _student.score = 100;
    }

    // 方法2:直接引用状态变量的struct
    function initStudent2() external{
        student.id = 1;
        student.score = 80;
    }
    
    // 方法3:构造函数式
    function initStudent3() external {
        student = Student(3, 90);
    }

    // 方法4:key value
    function initStudent4() external {
        student = Student({id: 4, score: 60});
    }
}

pragma solidity ^0.8.21;
contract EnumTypes {
    // 将uint 0, 1, 2表示为Buy, Hold, Sell
    enum ActionSet { Buy, Hold, Sell }
    // 创建enum变量 action
    ActionSet action = ActionSet.Buy;

    // enum可以和uint显式的转换
    function enumToUint() external view returns(uint){
        return uint(action);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/783228.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PyQT: 开发一款ROI绘制小程序

在一些基于图像或者视频流的应用中&#xff0c;比如电子围栏/客流统计等&#xff0c;我们需要手动绘制一些感兴趣&#xff08;Region of Interest&#xff0c;简称ROI&#xff09;区域。 在这里&#xff0c;我们基于Python和PyQt5框架开发了一款桌面应用程序&#xff0c;允许用…

java中Request和Response的详细介绍

1.Request和Response的概述 # 重点 1. service方法的两个参数request和response是由tomcat创建的void service(ServletRequest var1, ServletResponse var2) 2. request 表示请求数据, tomcat将浏览器发送过来的请求数据解析并封装到request对象中servlet开发者可以通过reques…

AI免费英语学习在线工具:Pi;gpt;其他大模型AI 英语学习智能体工具

1、pi(强烈推荐&#xff1a;可以安卓下载使用) https://pi.ai/talk &#xff08;网络国内使用方便&#xff09; 支持实时聊天与语音对话 2、chatgpt&#xff08;强烈推荐&#xff1a;可以安卓下载使用) https://chat.openai.com/ &#xff08;网络国内使用不方便&#xf…

element-ui el-select选择器组件下拉框增加自定义按钮

element-ui el-select选择器组件下拉框增加自定义按钮 先看效果 原理&#xff1a;在el-select下添加禁用的el-option&#xff0c;将其value绑定为undefined&#xff0c;然后覆盖el-option禁用状态下的默认样式即可 示例代码如下&#xff1a; <template><div class…

27_电子电路设计基础

电路设计 电路板的设计 电路板的设计主要分三个步骤&#xff1a;设计电路原理图、生成网络表、设计印制电路板。 (1)设计电路原理图&#xff1a;将元器件按逻辑关系用导线连接起来。设计原理图的元件来源是“原理图库”,除了元件库外还可以由用户自己增加建立新的元件&#…

@Builder注解详解:巧妙避开常见的陷阱

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 Builder注解详解&#xff1a;巧妙避开常见的陷阱 前言1. Builder的基本使用使用示例示例类创建对…

YOLOv5改进系列(32)——替换主干网络之PKINet(CVPR2024 | 面向遥感旋转框主干,有效捕获不同尺度上的密集纹理特征)

【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制 YOLOv5改进系列(2)——添加CBAM注意力机制 YOLOv5改进系列(3)——添加CA注意力机制 YOLOv5改进系列(4)——添加ECA注意力机制 YO…

21. Java AQS 原理

1. 前言 本节内容主要是对 AQS 原理的讲解&#xff0c;之所以需要了解 AQS 原理&#xff0c;是因为后续讲解的 ReentrantLock 是基于 AQS 原理的。本节内容相较于其他小节难度上会大一些&#xff0c;基础薄弱的学习者可以选择性学习本节内容或者跳过本节内容。 了解什么是 AQ…

从无计划到项目管理高手,只需避开这两大误区!

在项目管理的过程中&#xff0c;制定计划是不可或缺的一环。然而&#xff0c;在实践中&#xff0c;我们往往会遇到两种常见的误区&#xff0c;这些误区不仅阻碍了计划的有效实施&#xff0c;还可能让我们在追求目标的道路上迷失方向。 误区一&#xff1a;认为没有什么可计划的…

Nacos 国际化

项目需要&#xff0c;后端异常信息需要进行国际化处理。所有想有没有方便易用的可选项。 1、国际化配置调整&#xff0c;不需要重启系统 2、可支持添加不同或自定义语言包&#xff08;就是配置的资源文件&#xff09; 参考&#xff1a; Nacos实现SpringBoot国际化的增强_spr…

硅纪元视角 | Speak火了!3个月收入翻倍,OpenAI为何频频下注?

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

LabVIEW自动探头外观检测

开发了一套基于LabVIEW的软件系统&#xff0c;结合视觉检测技术&#xff0c;实现探头及连接器外观的自动检测。通过使用高分辨率工业相机、光源和机械手臂&#xff0c;系统能够自动定位并检测探头表面的细微缺陷&#xff0c;如划痕、残胶、异色、杂物等。系统支持多种探头形态&…

王老师 linux c++ 通信架构 笔记(二)

&#xff08;7&#xff09;本条目开始配置 linux 的固定 ip 地址&#xff0c;以作为服务器使用&#xff1a; 首先解释 linux 的网口编号&#xff1a; linux 命令 cd &#xff1a; change directory 改变目录。 ls &#xff1a; list 列出某目录下的文件 根目录文件名 / etc &a…

Kubernetes运维工程师必备:K8s 基础面试题精编(一)

Kubernetes运维工程师必备:K8s 基础面试题精编(一) 1. 什么是Kubernetes?2. Kubernetes如何实现容器编排?3. 说出k8s的常见资源对象?4. 什么是pod?5. Deployment介绍及使用?6. statefulesets介绍及使用?7. statefulesets和deployment区别?8. 什么是调度器(Scheduler…

三菱PLC 实现PID控制温度 手搓PID指令!!!

目录 1.前言 2.PID公式的讲解 3.程序 4.硬件介绍 5.EPLAN图纸 6.成果展示 7.结语 1.前言 新手想要学习PLC的PID控制 首先会被大串的PID 公式吓到 PID公式有很多种&#xff1a;基本PID 位置式 增量式 模拟式 理想型 等等 但是 不要急 别看这么多公式 其实 将公式拆…

知识图谱驱动的深度推理:ToG算法的创新与应用

LLMs通过预训练技术在大量文本语料库上生成连贯且符合上下文的响应。然而&#xff0c;面对需要复杂知识推理的任务时&#xff0c;它们存在明显的局限性。这些问题包括对超出预训练阶段的专业知识的准确回答失败&#xff0c;以及缺乏责任性、可解释性和透明度。为了解决这些问题…

(19)夹钳(用于送货)

文章目录 前言 1 常见的抓手参数 2 参数说明 前言 Copter 支持许多不同的抓取器&#xff0c;这对送货应用和落瓶很有用。 按照下面的链接&#xff08;或侧边栏&#xff09;&#xff0c;根据你的设置了解配置信息。 Electro Permanent Magnet v3 (EPMv3)Electro Permanent M…

教育相关知识

教育的含义 教育的基本要素 教育的属性 教育的功能 教育的起源 教育的发展

软件安全性测试的工具有哪些?

软件安全性测试是确保软件系统在设计和实施过程中能够保护系统的机密性、完整性和可用性。为了进行软件安全性测试&#xff0c;有许多工具可供选择&#xff0c;这些工具可以帮助测试人员发现潜在的安全漏洞和弱点&#xff0c;从而提高软件系统的安全性。 以下是一些常用的软件安…

两年经验前端带你重学前端框架必会的ajax+node.js+webpack+git等技术 Day2

前端框架必会的&#xff08;ajaxnode.jswebpackgit&#xff09;个人学习心得作业及bug记录 Day2 你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner &#x1f339; 如果本…