Rust---复合数据类型之结构体

目录

  • 结构体的使用
    • 输出结果
  • 结构体简化创建
  • 结构体更新语法
  • 元组结构体
  • 单元结构体(unit struct)
  • 结构体中的引用
  • 使用#[derive(Debug)]
    • 再次介绍
  • 代码综合展示

与元组不同的是,结构体可以为内部的每个字段起一个富有含义的名称,因此无需依赖这些字段的顺序就可以来访问和解析它们。

结构体的使用

// 定义一个结构体 Person
struct Person {name: String,age: u32,
}// 为 Person 结构体实现方法
impl Person {fn greet(&self) {println!("Hello, my name is {}.", self.name);}
}fn main() {// 创建一个 Person 结构体实例let mut person1 = Person {name: String::from("Alice"),age: 30,};// 修改 Person 结构体字段// 必须要将结构体实例声明为可变的,才能修改其中的字段,Rust 不支持将某个结构体某个字段标记为可变。person1.name = String::from("Amy");// 访问 Person 结构体字段println!("Name: {}", person1.name);println!("Age: {}", person1.age);// 调用 Person 结构体方法person1.greet();
}

输出结果

在这里插入图片描述

结构体简化创建

fn build_user(email: String, username: String) -> User {User {email,//当函数参数和结构体字段同名时,可以直接使用缩略的方式进行初始化username,//当函数参数和结构体字段同名时,可以直接使用缩略的方式进行初始化active: true,sign_in_count: 1,}
}

结构体更新语法

  • .. 语法表明凡是我们没有显式声明的字段,全部从 user1 中自动获取。
  • 需要注意的是 ..user1 必须在结构体的尾部使用。
  let user2 = User {email: String::from("another@example.com"),..user1};
  • 结构体更新语法跟赋值语句 = 非常相像,结果是,username 所有权被转移给了 user2,导致了 user1 无法再被使用。
  • 把结构体中具有所有权的字段转移出去后,将无法再访问该字段,但是可以正常访问其它的字段。

元组结构体

  • 元组结构体在某些情况下比普通结构体更方便,特别是当您只需要一个简单的数据结构来存储几个字段时。元组结构体可以帮助您更清晰地表达代码的意图,并且具有元组的轻量性和灵活性。
  • 结构体的字段可以没有名称,这种结构体长得很像元组。
// 定义一个类似元组的结构体 Color,表示颜色
struct Color(i32, i32, i32);// 定义一个类似元组的结构体 Point,表示三维空间中的点
struct Point(i32, i32, i32);fn main() {// 创建一个 Color 结构体实例,表示黑色let black = Color(0, 0, 0);// 创建一个 Point 结构体实例,表示原点let origin = Point(0, 0, 0);// 访问 Color 结构体的字段println!("Black: ({}, {}, {})", black.0, black.1, black.2);// 访问 Point 结构体的字段println!("Origin: ({}, {}, {})", origin.0, origin.1, origin.2);
}

单元结构体(unit struct)

  • 它不包含任何字段。单元结构体的定义非常简单,只是由结构体关键字 struct 后面跟结构体的名称构成,例如:
struct UnitStruct;
  • 单元结构体在 Rust 中主要用于表示不需要存储数据的类型,通常用作占位符、类型标记或模块化设计中的辅助类型。

结构体中的引用

  • 如果想在结构体中使用一个引用,就必须加上生命周期。
  • 生命周期能确保结构体的作用范围要比它所借用的数据的作用范围要小。

使用#[derive(Debug)]

  • 如果使用 {} 来格式化输出,那对应的类型就必须实现 Display 特征,结构体不默认实现 Display 特征。因此下面的代码会报错:
struct Rectangle {width: u32,height: u32,
}fn main() {let rect1 = Rectangle {width: 30,height: 50,};println!("rect1 is {}", rect1);
}
  • 如果改为:println!("rect1 is {:?}", rect1);
// 会提醒我们没有实现debug特征
error[E0277]: `Rectangle` doesn't implement `Debug`
  • 正确使用方法:
#[derive(Debug)]// 加上这一个东西
struct Rectangle {width: u32,height: u32,
}fn main() {let rect1 = Rectangle {width: 30,height: 50,};println!("rect1 is {:?}", rect1);
}

再次介绍

  • Rust 中,#[derive(Debug)] 是一个非常方便的属性,用于自动实现 Debug traitDebug trait 是一个用于打印调试信息的 trait,通过实现这个 trait,可以使用 println!("{:?}", variable); 这样的方式来输出变量的调试信息,而不需要手动实现 Debug traitfmt 方法。
  • #[derive(Debug)] 的使用可以简化代码,并让我们更方便地输出结构体、枚举等类型的调试信息。

代码综合展示

// 定义一个结构体 Person
struct Person {name: String,age: u32,
}// 为 Person 结构体实现方法
impl Person {fn greet(&self) {println!("Hello, my name is {}.", self.name);}
}// 定义一个元组结构体 Point
struct Point(i32, i32);// 定义一个结构体 Rectangle,并衍生 Debug 特性
#[derive(Debug)]
struct Rectangle {width: u32,height: u32,
}fn main() {// 创建一个 Person 结构体实例let person1 = Person {name: String::from("Alice"),age: 30,};// 访问 Person 结构体字段println!("Name: {}", person1.name);println!("Age: {}", person1.age);// 调用 Person 结构体方法person1.greet();// 创建一个可变 Person 结构体实例let mut person2 = Person {name: String::from("Bob"),age: 25,};// 修改 Person 结构体字段person2.age = 26;// 创建一个元组结构体实例let origin = Point(0, 0);// 创建一个 Rectangle 结构体实例let rect = Rectangle {width: 10,height: 20,};// 打印 Rectangle 结构体实例,使用 Debug 特性println!("{:?}", rect);
}

输出结果:【这个警告实在是不知道怎么修改,明明已经使用println!("{:?}", variable);了】
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【74LS191/48为可预置的四位二进制加/减法计数器3-9循环显示】2022-3-19

缘由我有电路原理图,想用proteus仿真,但是数码管不亮-嵌入式-CSDN问答 74LS191为可预置的四位二进制加/减法计数器 74ls191引脚功用 RCO进位/借位输出端 MAX/MIN进位/借位输出端 CTEN计数操控端 QA-QD计数输出端 U/D计数操控端 CLK时钟输入端 LO…

【Docker笔记03】【MySQL 与 Redis的主从安装】

一、前言 本系列是根据 B 站 尚硅谷 Docker 视频 学习记录笔记。因为没有视频课件,部分内容摘自 https://www.yuque.com/tmfl/cloud/dketq0。 本系列仅为自身学习笔记记录使用,记录存在偏差,推荐阅读原视频内容或本文参考笔记。 二、Mysql …

如何加速Docker镜像的构建过程?

要加速Docker镜像的构建过程,你可以考虑以下几种方法: 使用多阶段构建:多阶段构建可以帮助你减少镜像的大小,从而加速构建过程。你可以将构建过程分为多个阶段,每个阶段只保留必要的文件和依赖,最终构建出一…

10-用PySpark建立第一个Spark RDD

目录 RDD概念RDD特点建立RDD的方式不同工具建立RDD的方式使用PySpark Shell(交互环境)建立RDD使用VSCode编程建立RDD使用Jupyter Notebook建立RDD 总结 PySpark实战笔记系列第一篇 RDD概念 Apache Spark的核心组件的基础是RDD。所谓的RDD,即弹性分布式数据集&#…

Linux 关闭防火墙命令(新手)

关闭防火墙 查看防火墙状态 systemctl status firewalld.service 临时关闭防火墙(重启失效) systemctl stop firewalld.service 永久关闭防火墙 systemctl disable firewalld.servicesudo systemctl enable firewalld,这种方式输入命令…

施耐德 Unity Pro PLC 编程软件介绍

Unity Pro 软件基本介绍 Unity Pro 是施耐德中大型 PLC 的编程软件&#xff08;<–> 对应西门子 Step7&#xff09; 支持的 PLC&#xff1a;施耐德中大型 PLC 中型 PLC&#xff1a;Premium、M340&#xff08;<–> 对应西门子 S7-300、S7-1200&#xff09;大型 PL…

【C++】探索C++中的类与对象(上)

​​ &#x1f331;博客主页&#xff1a;青竹雾色间. &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ✨人生如寄&#xff0c;多忧何为 ✨ C是一种强大的编程语言&#xff0c;其面向对象的特性使得代码结构更加清晰、易于维护和扩展。在C中&#xff0c;类与…

常见docker使用命令

#搭建镜像 “”" sudo docker build -t es_refresh:V1.20230303 . “”" #启动容器 “”" docker run -d --namepara_classify -v /etc/localtime:/etc/localtime -v /data/chenhw/multi_label_classification:/edb2vec -p 8066:8066 --gpus ‘“device0”’…

Day83:服务攻防-开发组件安全JacksonFastJson各版本XStreamCVE环境复现

目录 J2EE-组件Jackson-本地demo&CVE 代码执行 (CVE-2020-8840) 代码执行 (CVE-2020-35728&#xff09; J2EE-组件FastJson-本地demo&CVE FastJson < 1.2.24 FastJson < 1.2.47 FastJson < 1.2.80 (利用条件比较苛刻) J2EE-组件XStream-靶场&CVE …

高度不同的流体瀑布css实现方法

商城商品列表 实现瀑布流展示&#xff0c;通过flex或grid实现会导致每行中的列高度一致&#xff0c;无法达到错落有致的感觉&#xff1b; 为此需要用到&#xff1a; CSS columns 属性 columns 属性是一个简写属性&#xff0c;用于设置列宽和列数。 CSS 语法 columns: column-wi…

如何让Webots支持C#语言开发的控制器

Webots支持C、C、Java、Python、Matlab这五种语言开发控制器&#xff0c;没有直接支持C#&#xff0c;但有个同事已经用C#写了大量的机器人控制代码&#xff0c;想在不把C#代码改写成C的情况下&#xff0c;直接用webots仿真&#xff0c;那就得想想办法。(不过&#xff0c;让Chat…

字节新作:图像生成质量超越DiT

&#x1f31f;每日更新最新高质量论文&#xff0c;关注我&#xff0c;时刻关注最新大模型进展。&#x1f31f; &#x1f4cc; 元数据概览&#xff1a; 标题&#xff1a;Visual Autoregressive Modeling: Scalable Image Generation via Next-Scale Prediction作者&#xff1a…

Java 内存占用过高应该如何优化

优化Java程序的内存占用是提高程序性能和稳定性的重要任务之一。内存占用过高可能导致系统性能下降、内存泄漏、频繁的垃圾回收等问题&#xff0c;影响程序的运行效率和用户体验。因此&#xff0c;对于Java程序内存占用过高的情况&#xff0c;需要采取一系列措施进行优化。 1.…

算法设计与分析实验报告java实现(排序算法、三壶谜题、交替放置的碟子、带锁的门)

一、 实验目的 1&#xff0e;加深学生对算法设计方法的基本思想、基本步骤、基本方法的理解与掌握&#xff1b; 2&#xff0e;提高学生利用课堂所学知识解决实际问题的能力&#xff1b; 3&#xff0e;提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 1、排序算法…

【随笔】Git 高级篇 -- 相对引用2(十三)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

面向对象9

面向对象9 一.内部类 1、什么是内部类&#xff1f; 将一个类A定义在另一个类B里面&#xff0c;里面的那个类A就称为内部类&#xff08;InnerClass&#xff09;&#xff0c;类B则称为外部类&#xff08;OuterClass&#xff09;。 2、为什么需要内部类&#xff1f; 具体来说…

操作系统八股|用户态和内核态

文章目录 内核态(Kernel Mode)用户态(User Mode)用户态和内核态之间的切换为什么要切换如何切换系统调用硬件中断异常处理 为了使操作系统内核提供⼀个⽆懈可击的进程抽象&#xff0c;处理器必须提供⼀种机制&#xff0c; 限制⼀个应⽤可以执⾏的指令以及他可以⽤来访问的地址…

4.4C++

1 #include <iostream> #include <cmath> using namespace std; class A{ private:int a;// 判断一个数是否为质数bool isP(int num) {if (num<2) return false;for (int i2;i<sqrt(num);i) {if (num % i 0) {return false;}}return true;} public:// 构造…

open-cd框架调试记录

源于论文Changer: Feature Interaction Is What You Need forChange Detection 源码位置&#xff1a;open-cd/README.md at main likyoo/open-cd (github.com) 同样是基于MMSegmentation框架的代码&#xff0c;不符合本人编程习惯所以一直也没有研究这东西&#xff0c;近期打…

Linux进程概念(二):进程的基本概念与进程的创建

目录 进程的基本概念 进程控制块-PCB 学前补充 预备知识 创建&#xff08;子&#xff09;进程 创建&#xff08;子&#xff09;进程的原因 理解fork有两个返回值 进程的基本概念 基本概念&#xff1a;程序的一个执行实例&#xff0c;正在执行的程序等 内核层面&#x…