rust学习六、简单的struct结构
一、结构定义
struct-翻译为结构/结构体
总体上有两种定义方式:带有详细属性名的;不带属性名(元组)
从工程角度出发,并不推荐不带属性的定义方式,因为不友好。希望rust后面不要搞类似好像很友好,但是其实起到干扰作用的语法。
如果再考虑到一些rust的其它问题,定义一个结构其实也不是那么容易。
示例:
struct Point{x:f64,y:f64}
struct Triangle(Point,Point,Point);
/**
* 家庭结构体s
*/
struct Family {
name: String,
father: String,
mather: String,
children: Vec<String>,
}
/**
* 这都什么狗屎语法。
*/
struct Book<'a> {
name: &'a str,
author: &'a str,
price: f64,
pubyear: i32,
}
fn main() {
let mut family = Family {
name: String::from("家"),
father: String::from("爸爸"),
mather: String::from("妈妈"),
children: vec![],
};
family.children.push(String::from("老大-独龙"));
family.children.push(String::from("老二-独眼"));
family.children.push(String::from("老三-独秀"));
family.children.push(String::from("老四-嘟嘟"));
family.children.push(String::from("老五-杜牧"));
//打印家庭结构体
println!(
"家庭:{},父亲:{},母亲:{}",
family.name, family.father, family.mather
);
for child in &family.children {
println!("孩子:{}", child);
}
let mut 三国演义 = Book {
name: "三国演义",
author: "罗贯中",
price: 29.8,
pubyear: 1300,
};
//各种创建结构实例的方式
// 方式一:双点号复制
let mut 红楼梦=Book{
name:"红楼梦",
author:"曹雪芹",
..三国演义
};
//方式二: 略属性名
let 西游记=write_book("西游记","吴承恩",24.0,1525);
//方式三:使用基于元组定义的。 比java的record还简单
let books=[三国演义,红楼梦,西游记];
for i in 0..books.len() {
print_book(&books[i]);
}
let p1=Point{x:10.0,y:20.0};
let p2=Point{x:20.0,y:20.0};
let p3=Point{x:20.0,y:10.0};
let t=Triangle(p1,p2,p3);
print_triangle(&t);
}
fn print_book(book:&Book){
println!(
"书名:{},作者:{},价格:{},出版年:{}",
book.name, book.author, book.price, book.pubyear
);
}
fn print_triangle(t:&Triangle){
println!("三点坐标:");
println!("{},{}",t.0.x,t.0.y);
println!("{},{}",t.1.x,t.1.y);
println!("{},{}",t.2.x,t.2.y);
}
fn write_book<'a>(name:&'a str,author:&'a str,price:f64,pubyear:i32)->Book<'a>{
Book{
name,
author,
price,
pubyear
}
}
在上例中,结构Book使用了非常奇怪的语法:
struct Book<'a> {
name: &'a str,
author: &'a str,
price: f64,
pubyear: i32,
}
这个能够定义出来,是因为编译器提示的。
作为初学者,先绕过这个吧。
rust结构体实例的属性赋值也有两种方式:
属性逐一赋值
双点号复制属性值
例如以下就是:
let mut 红楼梦=Book{
name:"红楼梦",
author:"曹雪芹",
..三国演义
};
二、几种打印方式
至少有4种打印方式:
逐一访问属性名
println!使用宏符号:?
println!使用宏符号:#?
使用dbg!
后面三种方式,要求定义结构的时候,在结构前添加
#[derive(Debug)]
这个东西应该怎么称呼了? "属性"还是"编译指示符"?,有点乱七八杂的。
从宏观上而言,很多类似的都是可以称为编译指示符,所以为了更加精准一些,我愿意称为"功能编译指示"。
通过这个功能编译指示,rust编译器会自动实现特定功能。
示例:
#[derive(Debug)]
struct Family{
father:String,
mather:String,
address:String
}
fn main(){
let mut mf=Family{
father:String::from("lu"),
mather:String::from("hu"),
address:String::from("中国")
};
println!("我家-{},{},{}",mf.father,mf.mather,mf.address);
print_family(&mf);
print_family_use_dbg(&mf);
}
fn print_family(f:&Family){
//你不能直接打印,否则会有奇奇怪怪的错误提示
//println!("{}",f); // 这个会提示错误,所以注释掉了
//使用奇怪符号 :?打印结构体
println!("我家:?-{:?}",f);
//使用奇怪的符号,可以打印结构体 :#?
println!("我家:#?-{:#?}",f);
}
fn print_family_use_dbg(f:&Family){
dbg!(f);
}
三、定义结构内的函数
在没有看书本正文之前,我以为和java的record一样,在struct内部定义函数。
其实不是! 如果要为结构体定义函数,必须在结构体外。 不知道为什么要那样? 难道内部定义的话,有其它用途?
示例:
#[derive(Debug)]
struct Cube{
length: u32,
width: u32,
height: u32,
}
impl Cube{
fn volume(&self) -> u32{
return self.length * self.width * self.height;
}
fn is_bigger_than(&self, other: &Cube) -> bool{
return self.volume() > other.volume();
}
}
fn main() {
let cube = Cube{length: 10, width: 12, height: 25};
let cube2 = Cube{length: 15, width: 10, height: 30};
println!("立方体的体积={}立方厘米",cube.volume());
let is_bigger = cube.is_bigger_than(&cube2);
match is_bigger{
true => println!("cube的体积{}大于cube2体积{}",cube.volume(), cube2.volume()),
false =>println!("cube的体积{}小于cube2体积{}",cube.volume(), cube2.volume()),
};
}
结构体的函数有几个特点:
在结构体外,使用impl xxxx {}的方式,其中xxx是结构体名称
在一个impl xxx{}结构中,可以定义多个函数
书本建议我们:函数的第一个方法总是 &self,这点和python有点类似
参数&self虽然有定义,但是调用的时候不需要显示传递,因为这是编译器实现的
四、一点小补充
4.1定义没有成员的结构
在很多OOP,允许我们定义没有成员的对象。
我们可以把struct大体当做对象。
在rust中也可以定义没有成员的结构,例如:
#[derive(Debug)]
struct NoItem;
struct NoItem2();
let nod=NoItem{};
println!("空结构体:{:?}",nod);
rust允许这样做,是因为struct这个类型具有很多作用,即使它不用于存储数据,也有很多作用。具体什么作用,只能等待深入后了解。
总之在rust中,绝大部分复杂的类型,都是基于结构定义的。
4.2struct大有作用
前有言:某种程度上可以把struct视为OOP中的对象
虽然rust不是明面上的OOP,但还是吸收了很多OOP的营养。
总之,许多复杂类型都是基于结构定义的。具体不一一罗列。
五、小结
结构体无疑是一个有用的东西,它就算垃圾袋/宝物袋一样,什么都可以往里装,大大方便了工程师!

关注灵活就业新业态,关注公账号:贤才宝
相关文章:
rust学习六、简单的struct结构
一、结构定义 struct-翻译为结构/结构体 总体上有两种定义方式:带有详细属性名的;不带属性名(元组) 从工程角度出发,并不推荐不带属性的定义方式,因为不友好。希望rust后面不要搞类似好像很友好ÿ…...
.NET周刊【2月第2期 2025-02-09】
国内文章 开箱即用的.NET MAUI组件库 V-Control 发布了! https://www.cnblogs.com/jevonsflash/p/18701494 文章介绍了V-Control,一个适用于.NET MAUI的组件库。作者计划将其开源,强调.NET MAUI是生产力强的跨平台移动开发工具。V-Control提供多种组件…...
Linux的基础指令和环境部署,项目部署实战(下)
目录 上一篇:Linxu的基础指令和环境部署,项目部署实战(上)-CSDN博客 1. 搭建Java部署环境 1.1 apt apt常用命令 列出所有的软件包 更新软件包数据库 安装软件包 移除软件包 1.2 JDK 1.2.1. 更新 1.2.2. 安装openjdk&am…...
【分布式理论15】分布式调度1:分布式资源调度的由来与过程
文章目录 一、操作系统的资源调度:从单核到多核二、 分布式系统的资源调度:从单台服务器到集群三、 固定资源映射四、 动态资源分配:灵活的任务-资源匹配五、 资源调度过程:从申请到执行 本文主要讨论主题: 从操作系统…...
Python常见面试题的详解12
1. hasattr ()、getattr ()、setattr () 函数是如何使用的? 要点 这三个函数用于对对象的属性进行检查、获取和设置操作,是 Python 中进行对象属性动态操作的重要工具。 hasattr():用于检查对象是否具有指定属性或方法。 getattr()&#x…...
未来AI方向落地场景:小语言模型,super_private_agent
未来AI方向落地场景:小语言模型,super_private_agent 目录 未来AI方向落地场景:小语言模型,super_private_agent小语言模型super - private - agent(注重隐私的智能代理)碳基生命和硅基生命交互界面面向agent的专用交互协议和数据接口从web平台经济到网络平台举例说明社交…...
使用 PyTorch 实现标准卷积神经网络(CNN)
卷积神经网络(CNN)是深度学习中的重要组成部分,广泛应用于图像处理、语音识别、视频分析等任务。在这篇博客中,我们将使用 PyTorch 实现一个标准的卷积神经网络(CNN),并介绍各个部分的作用。 什…...
开题报告——基于Spring Boot的垃圾分类预约回收系统
关于本科毕业设计(论文)开题报告的规定 为切实做好本科毕业设计(论文)的开题报告工作,保证论文质量,特作如下规定: 一、开题报告是本科毕业设计(论文)的必经过程,所有本科生在写作毕业设计(论文)之前都必须作开题报告。 二、开题报告主要检验学生对专业知识的驾驭能…...
YOLOv5 目标检测优化:降低误检与漏检
1. 引言 在目标检测任务中,误检(False Positive, FP)和漏检(False Negative, FN)是影响检测性能的两个主要问题。误检意味着模型检测到了不存在的目标,而漏检则指模型未能检测到真实存在的目标。本文将介绍…...
网络安全治理模型
0x02 知识点 安全的目标是提供 可用性 Avialability机密性 confidentiality完整性 Integrity真实性 Authenticity不可否认性 Nonrepudiation 安全治理是一个提供监督、问责和合规性的框架 信息安全系统 Information Security Management System ISMS 策略,工作程…...
网络原理-
文章目录 协议应用层传输层网络层 数据链路层 协议 在网络通信中,协议是非常重要的概念.协议就是一种约定. 在网络通信过程中,对协议进行了分层 接下来就按照顺序向大家介绍每一种核心的协议. 应用层 应用层是咱们程序员打交道最多的一层协议.应用层里有很多现成的协议,但…...
HTML/CSS中交集选择器
1.作用:选中同时符合多个条件的元素 交集就是或的意思 2.语法:选择器1选择器2选择器3......选择器n{} 3.举例: /* 选中:类名为beauty的p元素,此种写法用的非常的多 */p.beauty{color: red;}/* 选中:类名包含rich和beauty的元素 */.rich.beauty{color: blue;} 4.注意: 1.有标签…...
机器学习(1)安装Pytorch
1.安装命令 pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 2.安装过程Log: Looking in indexes: https://download.pytorch.org/whl/cu118 Co…...
Spring Boot过滤器链:从入门到精通
文章目录 一、过滤器链是什么?二、为什么需要过滤器链?三、Spring Boot中的过滤器链是如何工作的?(一)过滤器的生命周期(二)过滤器链的执行流程 四、如何在Spring Boot中定义自己的过滤器&#…...
vue3之echarts3D圆柱
vue3之echarts3D圆柱 效果: 版本 "echarts": "^5.1.2" 核心代码: <template><div ref"charts" class"charts"></div><svg><linearGradient id"labColor" x1"0&q…...
Redux中间件redux-thunk和redux-saga的具体区别是什么?
Redux 中间件是增强 Redux 功能的重要工具,redux-thunk 和 redux-saga 是两个常用的中间件,它们在处理异步操作和副作用时提供了不同的方式和理念。以下是两者的具体区别: 1. 概念与设计理念 redux-thunk 简洁:redux-thunk 是一…...
代码随想录算法训练营第四十三天| 动态规划06
322. 零钱兑换 如果求组合数就是外层for循环遍历物品,内层for遍历背包。 如果求排列数就是外层for遍历背包,内层for循环遍历物品。 这句话结合本题 大家要好好理解。 视频讲解:动态规划之完全背包,装满背包最少的物品件数是多少&…...
UI自动化教程 —— 元素定位技巧:精确找到你需要的页面元素
引言 在UI自动化测试中,准确地定位页面元素是至关重要的。无论是点击按钮、填写表单还是验证页面内容,都需要首先找到相应的页面元素。Playwright 提供了多种方法来实现这一点,包括使用CSS选择器和XPath进行元素定位,以及利用文本…...
MySQL六大日志的功能介绍。
前言 首先,MySQL的日志应该包括二进制日志(Binary Log)、错误日志(Error Log)、查询日志(General Query Log)、慢查询日志(Slow Query Log)、重做日志(Redo …...
二级指针略解【C语言】
以int** a为例 1.二级指针的声明 a 是一个指向 int*(指向整型的指针)的指针,即二级指针。 通俗的讲,a是一个指向指针的指针,对a解引用会是一个指针。 它可以用于操作动态分配的二维数组、指针数组或需要间接修改指针…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
