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);了】
在这里插入图片描述

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

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

相关文章

基于SpringBoot+Vue的汽车租赁管理系统的设计和实现【附源码】

1、系统演示视频(演示视频) 2、需要交流和学习请联系

vivado适用于 UltraScale 和 UltraScale+ 器件的 eFUSE 寄存器访问和编程

FUSE_DNA : 唯一的器件 DNA 每个 UltraScale 器件都有唯一的器件 ID , 称为器件 DNA , 且赛灵思已将此 DNA 编程到器件中。用户无法对 FUSE_DNA 进行编程。 UltraScale 器件具有 96 位 DNA 。您可在 Vivado Design Suite Tcl 控制台中…

Matlab梁单元有限元编程:铁木辛柯梁VS欧拉梁

专栏导读 作者简介:工学博士,高级工程师,专注于工业软件算法研究本文已收录于专栏:《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现,并提供所有案例完整源码;2.单元…

openplc Linux 地址映射io,读写驱动数据等使用记录

1. 上一篇记录 openplc使用C语言文件读写驱动实现基本流程。 openPLC_Editor C语言编程 在mp157 arm板上调用io等使用记录_openplc c 编程-CSDN博客 2. 下面通过映射地址的方式控制io和读写驱动数据。 在runtime 环境的 hardware 硬件配置中 选择 python on Linux(PSM)&#…

成为先进企业应该从用飞书开始,还是应该从裁员开始?

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 大家都觉得飞书不行了,我们反而不这么看。 众所周知,飞书最近裁员的消息在业界引起了巨大的反响,大…

基于SSM+Jsp+Mysql的快递管理系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

62、服务攻防——框架安全CVE复现SpringStrutsLaravelThinkphp

文章目录 常见语言开发框架(主流): PHP:ThinkPHP、Laravel、YIIJAVA:Spring、SpringbootPython:FlaskJavaScript:Vue.js、Node.js 框架判断(): 通过插件Wappalyzer(可能…

练手项目层初阶1—《详解静态版本——通讯录管理系统》

文章目录 🚩前言🔊 项目需求📚 项目知识点包含🧩项目框架📝框架拆解分析✨Struct_book.h 头文件解析✨Struct_book.c文件解析✨test_book.c文件解析 📺演示效果🚀完整代码 🚩前言 俗…

联想 Y9000P 连接网线速度慢 的 问题解决

参考帖子:求助,拯救者Y9000P 2022 i73060版本 有线网非常慢 无线网正常【笔记本吧】_百度贴吧 问题原因: 网卡驱动版本不对。不能用Win11版,要用Win10版。 问题解决: 1、卸载原驱动 2、下载Win10 驱动 并安装 下载…

C语言——常用库函数的使用及模拟实现

C语言编译系统为使用者提供了很多的预定义库函数。用户在编写程序时,可以直接调用这些库函数。这里选择了一些常用的库函数,简单介绍各个函数的使用方法: 字符串函数 字符串函数函数分为长度不受限制的字符串函数,和长度受限制的…

手搓链表(java)(不完整)

手搓链表(java)(不完整) 文章目录 手搓链表(java)(不完整)前言一、代码1.MyLinkedList类:2.测试类: 总结 前言 提示:以下是本篇文章正文内容&…

Git 术语及中英文对照

完毕!!感谢您的收看 ----------★★历史博文集合★★---------- 我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字…

保姆级教程——VLAN综合实验(不同VLAN通过动态路由访问外网)

前言: 部署了VLAN的传统交换机不能实现不同VLAN间的二层报文转发,因此必须引入路由技术来实现不同VLAN间的通信。VLAN路由可以通过二层交换机配合路由器来实现,也可以通过三层交换机来实现 VLAN间通信的限制 每个VLAN都是一个独立的…

vue 使用自定义标签URL Protocol 调用本地exe 并传参

创建注册表文件reg,并运行 里面的路径需要替换成实际exe的绝对路径 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\App] "URL:App Protocol Handler" "URL Protocol""" [HKEY_CLASSES_ROOT\App\DefaultIcon] &qu…

启动mysql

删除C:\Program Files (x86)\MySQL\MySQL Server 5.7这个路径下的data文件夹,这个很难删除,因为一开机,mysql的某些服务就启动了,每次重新启动mysql之前,都要删除这个文件夹 因为这个文件夹在后端执行一些我们看不到的…

pycharm打包python文件为exe文件(图文教程)

1.安装pyinstaller库 pip3 install pyinstaller 2.使用pyinstaller 打包文件 首先确保Terminal命令行中,你的路径和你的项目是同一个路径 我的项目就是放在golden_dev中的。 3.命令行内输入打包代码 pyinstaller -F -w gold_miner.py gold_miner.py 是我的项目…

HomePlug AV

目录 HomePlug AV的基本概念基本术语网络概念网络实例 HomePlug AV物理层(PHY)HomePlug AV OFDM收发器架构PHY的调制模式FC调制和ROBO调制物理层的特点OFDM频域/时域转换开窗/槽式OFDM信号和噪声PHY发送控制——信道自适应PHY帧格式(Symbol&a…

微软邮箱被锁住,该如何解除限制?

ChatGPT账号是微软邮箱注册的,我们在登陆微软邮箱时,http://www.outlook.com,不需要开魔法工具,直接就可以登陆,否则会出现安全验证,限制登陆。 那么如果账号被锁,我们该如何解除限制呢&#x…

目标检测——监控下的汽车

一、重要性及意义 首先,车辆检测技术是保证视频监控系统正常运行的基础。通过监控摄像头实时获取的图像,可以自动检测出图像中的车辆,并进行车辆类型的分类和识别。这对于优化城市交通管理、实现智能交通系统具有重要意义。此外,…

【LeetCode热题100】51. N 皇后(回溯)

一.题目要求 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方…