当前位置: 首页 > news >正文

【Rust自学】5.1. 定义并实例化struct

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

5.1.1. 什么是struct

struct的中文意思为结构体,它是一种自定义的数据类型,它允许程序为相关联的值命名和打包,形成有意义的组合。它类似于其他编程语言中的“类”或“结构”,但它只提供数据存储功能,不包含方法。

学过C/C++的人可能对struct这个关键字很熟悉,但它们有区别:

  • C:struct 是一种用来组织数据的简单聚合类型。它只能包含数据,没有方法。

  • C++:struct 与 class 非常相似,可以包含数据和方法,唯一的语法区别是在 struct 中,默认的访问权限是 public;在 class 中,默认的访问权限是 private。

  • Rust:struct 仅用于定义数据结构,不包含方法,方法需要通过 impl 块为结构体定义。Rust 提供了更严格的所有权、生命周期和内存管理机制。

5.1.2. 定义struct

  • 使用struct这个关键字,为整个struct命名(驼峰命名法)
  • 在花括号内,为所有字段(Field) 定义 名称类型

例子:
为HLTV上的CS职业选手定制存储各项数据的struct(补充信息:CS职业选手的数据一般由Rating评分、DPR每回合死亡数、KAST不白给率、Impact影响力、ADR平均每回合伤害、KPR每回合击杀数组成)
请添加图片描述

struct Stats{  rating: f32,  dpr: f32,  kast: f32,  impact: f32,  adr: f32,  kpr: f32,  
}

5.1.3. 实例化struct

想要使用struct,需要创建struct的实例:

  • 为每个字段指定具体值,不能少赋字段的值
  • 无需按声明的顺序进行指定

就以donk为例创建他的数据库:

fn main() {  let donk = Stats {  rating: 1.27,  impact: 1.4,  dpr: 0.67,  adr: 88.8,  kast: 74.1,  kpr: 0.85,  };  
}

5.1.4. 取得struct里某个字段的值

使用点标记法可以取得struct里字段的值:

fn main() {  let mut donk = Stats {  rating: 1.27,  impact: 1.4,  dpr: 0.67,  adr: 88.8,  kast: 74.1,  kpr: 0.85,  };  donk.rating = 2.59;  
}

如果要更改struct的值,记得在实例化时使用可变变量关键字mut

在struct中,可变性的最小单位就是单个实例,不能控制单个字段的可变性。一旦struct实例被声明为可变的,那么这个实例下的所有字段都是可变的。

5.1.5. 使用struct作为函数返回值

函数里的最后一个表达式就是它的返回值,所以使用struct作为返回值就只需要确保构建struct是这个函数的最后一个表达式(不带分号)就行:

fn change_stats(rating: f32, impact:f32, dpr:f32, adr:f32, kast:f32, kpr:f32) -> Stats{  Stats {  rating: rating,  impact: impact,  dpr: dpr,  adr: adr,  kast: kast,  kpr: kpr,  }  
}

5.1.6. 字段初始化的简写

Rust与JS和C#一样在某些情况下它的字段初始化是可以简写的

当字段名与字段值对应变量名相同时,就可以简写。比如在上一个代码例中,所有的字段名都和字段值对应的变量名相同,所以可以将其简写为:

fn change_stats(rating: f32, impact:f32, dpr:f32, adr:f32, kast:f32, kpr:f32) -> Stats{  Stats {  rating,  impact,  dpr,  adr,  kast,  kpr,  }  
}

当然不只是全部对应才能这么写,只要有一个字段符合简写条件就可以,其他的保持正常写法就行。

5.1.7. struct的更新语法

当你基于某个struct实例来创建一个新的实例的时候,如果新实例的字段有与先前实例里的字段相同的,就可以使用更新语法。

比如我要给存储sh1ro的数据,他的rating是1.25,impact是1.2,其余与donk一样,这是基础的写法:

fn main() {  let donk = Stats {  rating: 1.27,  impact: 1.4,  dpr: 0.67,  adr: 88.8,  kast: 74.1,  kpr: 0.85,  };  let sh1ro = Stats {  rating: 1.25,  impact: 1.2,  dpr: donk.dpr,  adr: donk.adr,  kast: donk.kast,  kpr: donk.kpr,};  
}

这样写比较麻烦,所以Rust提供了这样的语法糖:

fn main() {  let donk = Stats {  rating: 1.27,  impact: 1.4,  dpr: 0.67,  adr: 88.8,  kast: 74.1,  kpr: 0.85,  };  let sh1ro = Stats {  rating: 1.25,  impact: 1.2,  ..donk  };  
}

只需要写有变化的部分,其余一样的部分只需要写..加上另一个struct实例的名字即可,表示剩下的没有赋值的字段的值都与另一个实例对应字段的值相同

5.1.8. 元组结构体Tuple struct

其中文名叫做元组结构体,指的是类似元组的结构体。元组结构体整体有名字,但里面的元素没有。适用于想给整个tuple起名,并让它不同于其他tuple,而且又不需要给每个元素起名。

定义tuple struct:使用struct关键字,后边是名字,以及里面元素的类型。

例子:

struct Color(u8, u8, u8);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);

有的人戏谑地说:tuple struct在传统编程语言没有类似物,这是来自Haskell的高贵血统。这是因为在许多传统的面向对象语言(如 Java、C++)中,结构体或类是具名且字段命名的,而元组则是匿名且仅基于顺序的。没有中间形式来融合两者的优点。Rust的 tuple struct 概念与Haskell的新类型(Newtype Pattern) 有直接关系,Haskell中可以通过newtype来定义类似的模式。

需要注意的是,即使两个元组结构体有相同数量的元素并且对应元素的数据类型都一样,它们也不该被称为相同的类型,因为它们是不同的struct。

5.1.9. 类单元结构体Unit-Like Struct

unit-like struct被称为类单元结构体,因为它们的行为类似于单元类型()。当需要类型标记或是在某种类型上实现trait(可以理解为接口)但不想要在类型本身中存储任何数据时。类似于Go语言中的interface{}

struct ReadOnly;
struct WriteOnly;fn process_data<T>(_mode: T) {// 仅用于类型标记
}fn main() {process_data(ReadOnly);process_data(WriteOnly);
}

这个例子实现了类型标记

5.1.10. struct数据的所有权

struct User { 
active: bool, 
username: String, 
email: String, 
sign_in_count: u64, 
}

在这个例子中,usernameemail都使用的是String类型而不是&str,因为String类型是自有类型(owned type),拥有自身全部数据的所有权。在这种情况下,只要它的实例是有效的,那么里面的字段数据也肯定是有效的。

&str这样的引用类型也可以存放进struct里,但这需要生命周期(以后讲)。在这里先简单地来说,生命周期保证只要struct实例是有效的,那么里面的引用也是有效的。如果struct里面存储引用,而不使用生命周期,就会报错(missing lifetime specifier)。

相关文章:

【Rust自学】5.1. 定义并实例化struct

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 5.1.1. 什么是struct struct的中文意思为结构体&#xff0c;它是一种自定义的数据类型&#xff0c;它允许程序为相关联的值命名和打包&am…...

React 生命周期完整指南

React 生命周期完整指南 1. 生命周期概述 1.1 React 16.3 之前的生命周期 初始化阶段 constructorcomponentWillMountrendercomponentDidMount 更新阶段 componentWillReceivePropsshouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate 卸载阶段 componentWil…...

python中os._exit(0) 强制关闭进程后来杀死线程

在 Python 中调用 os._exit(0) 会强制终止整个进程&#xff0c;包括所有正在运行的线程。以下是详细解释&#xff1a; os._exit(0) 的行为 立即终止进程&#xff1a;os._exit() 函数会立即终止当前进程&#xff0c;不会执行任何清理操作&#xff0c;如调用清理处理程序&#…...

LeetCode:257. 二叉树的所有路径

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;257. 二叉树的所有路径 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根…...

RSICV国产芯片之CHV208

1. 芯片选型分析的对比维度 分析或者对标应用的芯片替代思路 1.1 内核/主频/存储空间支持 内核能力/指令集支持&#xff08;考虑工具链兼容性&#xff09;&#xff1b; 主频&#xff1a;对比计算能力是否满足基本要求 存储&#xff1a;内存--数据搬移空间决定数据运算的…...

理解神经网络

神经网络是一种模拟人类大脑工作方式的计算模型&#xff0c;是深度学习和机器学习领域的基础。 基本原理 神经网络的基本原理是模拟人脑神经系统的功能&#xff0c;通过多个节点&#xff08;也叫神经元&#xff09;的连接和计算&#xff0c;实现非线性模型的组合和输出。每个…...

Android 之 List 简述

一、简单创建方式 Android 开发中&#xff0c;列表有很多种类&#xff0c;如ArrayList、LinkedList、List、MutableList等&#xff0c;创建列表的方式如下所示&#xff1a; fun listDemo() {// 使用 listOf 创建不可变的空列表val list listOf<Int>()val list1 listOf…...

设计模式の中介者发布订阅备忘录模式

文章目录 前言一、中介者模式二、发布订阅模式三、备忘录模式 前言 本篇是关于设计模式中介者模式、观察者&#xff08;发布-订阅&#xff09;模式、以及备忘录模式的学习笔记。 一、中介者模式 中介者模式是一种行为型设计模式&#xff0c;其核心目的是为了减少对象之间的复杂…...

云手机群控能用来做什么?

随着云手机的发展&#xff0c;云手机群控技术逐渐从小众的游戏多开工具&#xff0c;发展为涵盖多个领域的智能操作平台。不论是手游搬砖、短视频运营&#xff0c;还是账号养成等场景&#xff0c;云手机群控都展现出了强大的应用潜力。本文将为大家详细解析云手机群控的应用场景…...

fpgafor循环语句使用

genvar i;//循环变量名称 generate for(i0;i<4;ii1)begin:tx//自己定义名称 //循环内容 end endgenerate12位的16进制乘以4就是48位位宽的2进制 因为 222*2(2^4)16...

【FastAPI】BaseHTTPMiddleware类

一、概述 在FastAPI中&#xff0c;BaseHTTPMiddleware 类是Starlette框架提供的一个抽象基类&#xff0c;它允许开发者基于HTTP请求/响应接口编写ASGI中间件。 这个类对于希望实现自定义中间件逻辑的开发者来说是非常重要的工具。 通过继承 BaseHTTPMiddleware 并实现特定的方…...

Solon v3.0.5 发布!(Spring 可以退休了吗?)

Solon 框架&#xff01; 新一代&#xff0c;面向全场景的 Java 应用开发框架。从零开始构建&#xff08;非 java-ee 架构&#xff09;&#xff0c;有灵活的接口规范与开放生态。 追求&#xff1a; 更快、更小、更简单提倡&#xff1a; 克制、高效、开放、生态 有什么特点&am…...

网络安全攻防演练中的常见计策

大家觉得有意义记得关注和点赞&#xff01;&#xff01;&#xff01; 引言 在网络安全攻防演练里面&#xff0c;用于分析攻击者动机和行为的&#xff0c;国外的有基于攻击链分析的模型&#xff08;如Cyber Kill Chain和ATT&CK&#xff09;和基于威胁行为的模型&#xff08…...

SD卡模块布局布线设计

1、SD/TF/SIM卡的定义 2、SD/TF/SIM卡模块引脚定义以及图示 3、SD/TF/SIM卡接口布局和布线 4、小结 1、BGA两线交叉时&#xff0c;可以在源头将两线互相短路连接&#xff0c;然后再输出口删除一小节线&#xff0c;然后CHRLX/V&#xff0c;这样就可以换两条线的网络&#xff0c…...

Flask-----SQLAlchemy教程

存session session[username] username # 存储数据到 session 取session username session.get(username) render_template return render_template(index.html, usernameAlice)&#xff0c;渲染一个包含 username 变量的模板。 redirect return redirect(url_for(profil…...

STM32 高级 物联网通信之CAN通讯

目录 CAN通讯介绍 物理层 协议层 CAN的帧(报文)种类 1 数据帧(发送单元->接受单元) 2 远程帧(接受单元->发送单元) 3 错误帧(发送方发送数据错误会发送的状态帧) 4 过载帧(接收方放不下会发送到的状态帧) 5 帧间隔(状态) 数据帧介绍 远程帧介绍 C…...

“乡村探索者”:村旅游网站的移动应用开发

3.1 可行性分析 从三个不同的角度来分析&#xff0c;确保开发成功的前提是有可行性分析&#xff0c;只有进行提前分析&#xff0c;符合程序开发流程才不至于开发过程的中断。 3.1.1 技术可行性 在技术实现层次&#xff0c;分析了好几种技术实现方法&#xff0c;并且都有对应的成…...

前端案例---自定义鼠标右键菜单

之前右击出现默认的选项菜单&#xff0c;使用evt.preventDefault()把默认的去掉&#xff0c;然后自定义右击的样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible"…...

浅谈归一化

在深度学习中&#xff0c;对网络层进行归一化&#xff08;Normalization&#xff0c;简称Norm&#xff09;是一个重要的技巧。常见的归一化方法包括批归一化&#xff08;Batch Normalization&#xff09;、层归一化&#xff08;Layer Normalization&#xff09;、实例归一化&am…...

lodash常用函数

文章目录 一、数组1、chunk分组2、difference、differenceBy、differenceWith3、findIndex4、intersection、intersectionBy、intersectionWith5、union、unionBy、unionWith 二、对象1、pick、omit 2、get、set三、数学1、sum、sumBy2、range 四、工具函数1、isEqual、isEmpty…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...