rust结构体
一、定义结构体类型
语法
struct Name_of_structure {field1: data_type,field2: data_type,field3: data_type,
}
注意:
不同于C++,Rust的struct语句仅用来定义类型,不能定义实例。
结尾不需要;。
每个字段定义之后用 , 分隔。最后一个逗号可有可无。
例子
struct Site {domain: String,name: String,nation: String,found: u32,
}
二、定义结构体实例
1.语法
let instance_name = Name_of_structure {field1: value1,field2: value2,field3: value3,
};
Rust受JavaScript影响,使用JSON对象的key: value语法定义结构体的实例
例子
let runoob = Site {domain: String::from("www.runoob.com"),name: String::from("RUNOOB"),nation: String::from("China"),found: 2013,
};
2.如果字段名称和变量名称一样,可以简化书写:
例子
let domain = String::from("www.runoob.com");
let name = String::from("RUNOOB");
let runoob = Site {domain, // 等同于domain : domain,name, // 等同于name : name,nation: String::from("China"),found: 2013,
};
3.复制现成的实例,只修改部分字段,可以使用如下语法
let site = Site {domain: String::from("www.xx.com"),name: String::from("xx"),..runoob,
};
这种语法要求至少重新设定一个字段的值
三、元组结构体
(一)
元组结构体的形式是元组,与元组的区别是它有名字和固定的类型格式。
它的意义是为了处理那些需要定义类型又不想太复杂的简单数据:
struct Color(u8, u8, u8);
struct Point(f64, f64);
let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);
元组结构体的使用方式和元组一样,通过 . 和下标来访问
例子
fn main() {struct Color(u8, u8, u8);struct Point(f64, f64);let black = Color(0, 0, 0);let origin = Point(0.0, 0.0);println!("black = ({}, {}, {})", black.0, black.1, black.2);println!("origin = ({}, {})", origin.0, origin.1);
}
运行结果:
black = (0, 0, 0)
origin = (0, 0)
(二)newtype模式
newtype模式是使用元组结构体创建一个新类型,这个元组结构体只有一个字段,相当于对这个字段类型的封装。
newtype模式的用处
1.newtype模式可以用于确保某值不被混淆
例子
Years和Days结构体都封装了i64值。
struct Years(i64);
struct Days(i64);
impl Years {pub fn to_days(&self) -> Days {Days(self.0 * 365)}
}
impl Days {pub fn to_years(&self) -> Years {Years(self.0 / 365)}
}
fn old_enough(age: &Years) -> bool {age.0 >= 18
}
fn main() {let age = Years(5);let age_days = age.to_days();println!("Old enough {}", old_enough(&age));println!("Old enough {}", old_enough(&age_days.to_years()));// println!("Old enough {}", old_enough(&age_days));
}
取消最后一行的注释,就会报错。传给old_enough的参数类型必须是Years类型的。
2.为外部类型实现外部trait
参考Rust特性
四、单元结构体
结构体可以没有任何成员,称为单元结构体。
struct MyStruct;
五、使用结构体
(一)输出结构体
以Debug方式打印结构体,需要实现Debug特性。
实例
#[derive(Debug)]
struct Rectangle {width: u32,height: u32,
}
fn main() {let rect1 = Rectangle { width: 30, height: 50 };println!("rect1 is {:?}", rect1);
}
输出一整个结构体:
rect1 is Rectangle { width: 30, height: 50 }
(二)访问结构体实例的元素
1.只读访问
使用元素访问符,也就是点号 ( . )
语法格式如下
struct_name_instance.field_name
范例
struct Employee {name: String,company: String,age: u32
}
fn main() {let emp1 = Employee {company:String::from("TutorialsPoint"),name:String::from("Mohtashim"),age:50};println!("Name is :{} company is {} age is {}", emp1.name, emp1.company, emp1.age);
}
编译运行结果如下
Name is :Mohtashim company is TutorialsPoint age is 50
2.修改结构体实例的字段
添加 mut 关键字,让它变成可修改的。
范例
struct Employee {name:String,company:String,age:u32
}
fn main() {let mut emp1 = Employee {company:String::from("TutorialsPoint"),name:String::from("Mohtashim"),age:50};emp1.age = 40;println!("Name is :{} company is {} age is {}", emp1.name, emp1.company, emp1.age);
}
编译运行结果如下
Name is :Mohtashim company is TutorialsPoint age is 40
(三)结构体作为函数的参数
例子
//定义一个结构体
struct Employee {name:String,company:String,age:u32
}
fn main() {//初始化结构体let emp1 = Employee {company:String::from("TutorialsPoint"),name:String::from("Mohtashim"),age:50}; let emp2 = Employee{company:String::from("TutorialsPoint"),name:String::from("Kannan"),age:32};//将结构体作为参数传递给displaydisplay(emp1);display(emp2);
}
fn display( emp: Employee){println!("Name is :{} company is {} age is {}", emp.name, emp.company, emp.age);
}
编译运行结果如下
Name is :Mohtashim company is TutorialsPoint age is 50
Name is :Kannan company is TutorialsPoint age is 32
(四)结构体实例作为函数的返回值
语法格式
struct My_struct {}
fn function_name([parameters]) -> My_struct {// 其它的函数逻辑return My_struct_instance;
}
范例
fn main() {let emp1 = Employee{company:String::from("TutorialsPoint"),name:String::from("Mohtashim"),age:50};let emp2 = Employee {company:String::from("TutorialsPoint"),name:String::from("Kannan"),age:32};let elder = who_is_elder(emp1,emp2);println!("elder is:");display(elder);
}
//接受两个Employee的实例作为参数并返回年长的那个
fn who_is_elder (emp1:Employee,emp2:Employee)->Employee {if emp1.age>emp2.age {return emp1;} else {return emp2;}
}
// 显示结构体的所有元素
fn display( emp: Employee) {println!("Name is :{} company is {} age is {}",emp.name,emp.company,emp.age);
}
// 定义一个结构体
struct Employee {name:String,company:String,age:u32
}
编译运行结果如下
elder is:
Name is :Mohtashim company is TutorialsPoint age is 50
六、结构体方法
关联函数是与一个类型相关联的函数。相当于成员函数。
如果关联函数的第一个参数名为 self,则此关联函数称为方法。
方法和函数的区别就是,方法是用来操作结构体实例的,而函数则不是。
为了方便,我们称方法为成员方法,关联函数我们称为成员函数。
(一)定义
1.成员方法
如果你学习过一些面向对象的语言,那你一定很清楚函数一般放在类定义里并在函数中用this表示所操作的实例。
结构体方法的第一个参数必须是 &self,不需指定类型,因为self是关键字。
与 C++不同的是,Rust中的结构体方法只能定义在结构体的外面。
使用 impl 关键字定义结构体,语法格式如下
struct My_struct {}
impl My_struct {// 定义一个方法fn method_name(&self[,other_parameters]) {//方法的具体逻辑代码}
}
结构体impl块可以写多次,效果相当于它们内容的拼接
结构体方法内部访问结构体字段
使用 self. 来访问结构体的元素。
例子
struct My_struct {age: u32
}
impl My_struct {//定义一个方法fn method_name([other_parameters]) {self.age = 28;println!("{}",self.age);//其它的具体逻辑代码}
}
2.成员函数
成员函数没有 &self参数。
语法格式如下
impl Structure_Name {fn method_name(param1: datatype, param2: datatype) -> return_type {// 方法内部逻辑}
}
例子
#[derive(Debug)]
struct Rectangle {width: u32,height: u32,
}
impl Rectangle {fn create(width: u32, height: u32) -> Rectangle {Rectangle { width, height }}
}
fn main() {let rect = Rectangle::create(30, 50);println!("{:?}", rect);
}
运行结果:
Rectangle { width: 30, height: 50 }
(二)调用
1.调用成员方法
方法可以使用方法调用操作符(.)来调用
语法格式为
My_struct.method_name([other_parameters])
注意,在调用结构体方法的时候不需要填写self,这个参数的传递Rust编译器会 偷偷的 帮我们完成。
实例
struct Rectangle {width: u32,height: u32,
}
impl Rectangle {fn area(&self) -> u32 {self.width * self.height}
}
fn main() {let rect1 = Rectangle { width: 30, height: 50 };println!("rect1's area is {}", rect1.area());
}
输出结果:
rect1's area is 1500
2.调用成员函数
直接通过结构体名调用,而无需实例。
使用路径来调用
语法格式如下
structure_name::method_name(v1,v2)
范例
//声明结构体Point
struct Point {x: i32,y: i32,
}
impl Point {fn get_instance(x: i32, y: i32) -> Point {Point { x: x, y: y }}fn display(&self){println!("x ={} y={}",self.x,self.y );}
}
fn main(){let p1 = Point::get_instance(10,20);p1.display();
}
编译运行结果如下
x =10 y=20
相关文章:
rust结构体
一、定义结构体类型 语法 struct Name_of_structure {field1: data_type,field2: data_type,field3: data_type, }注意: 不同于C,Rust的struct语句仅用来定义类型,不能定义实例。 结尾不需要;。 每个字段定义之后用 , 分隔。最后一个逗号可…...
Python - 小玩意 - 键盘记录器
pip install keyboardimport keyboard import timedef get_time():date_time time.strftime("%Y-%m-%d %H:%S", time.localtime())return date_timedef abc(x):if x.event_type down:print(f"{get_time()}你按下了{x.name}")with open(./键盘记录器.txt,…...
msvcp71.dll丢失的解决方法分享,全面分析msvcp71.dll丢失原因
msvcp71.dll 丢失的问题可能困扰着许多使用 Windows 操作系统的用户。msvcp71.dll 是微软 C运行时库中的一个动态链接库文件,负责提供一些基本的函数和类,例如字符串处理、数学运算、文件操作等。如果这个文件丢失或损坏了,那么在使用依赖于它…...
stm32----ADC模数转换
一、ADC介绍 ADC,即模数转换器,它可以将模拟信号转化为数字信号。在stm32种一般有3个ADC,每个ADC有18个通道。 12位ADC是一种逐次逼近型模拟数字转换器,它有多达18个通道,可测量16个外部和两个内部信号源。各个通道的A…...
Unity SteamVR 开发教程:用摇杆/触摸板控制人物持续移动(2.x 以上版本)
文章目录 📕教程说明📕场景搭建📕创建移动的动作📕移动脚本⭐移动⭐实时调整 CharacterController 的高度 📕取消手部和 CharacterController 的碰撞 持续移动是 VR 开发中的一个常用功能。一般是用户推动手柄摇杆&…...
04条件构造器和常用接口
条件构造器和常用接口 wapper介绍 条件构造器的两个条件之间默认就是AND并列关系,如果需要或者的关系则需要调用构造器的or()方法 条件构造器类型作用Wrapper条件构造抽象类,最顶端父类AbstractWrapper生成SQL的where条件QueryWrapper封装查询或删除的条件UpdateWrapper封装修…...
什么是HTTP状态码?常见的HTTP状态码有哪些?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是HTTP状态码?⭐ 1xx - 信息性状态码⭐ 2xx - 成功状态码⭐ 3xx - 重定向状态码⭐ 4xx - 客户端错误状态码⭐ 5xx - 服务器错误状态码⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前…...
vue3的双向绑定原理分析
谈到vue3的双向绑定原理,就得先知道,为什么vue2的双向绑定方式会被废弃? vue2的双向绑定 Object.defineProperty Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回…...
MySQL数据库时间计算的用法
今天给大家分享如何通过MySQL内置函数实现时间的转换和计算,在工作当中,测试人员经常需要查询数据库表的日期时间,但发现开发人员存入数据库表的形式都是时间戳形式,不利于测试人员查看,测试人员只能利用工具对时间戳进…...
应用在儿童平板防蓝光中的LED防蓝光灯珠
现在电子产品多,手机、平板电脑、电子书等等,由于蓝光有害眼睛健康,于是市场上有很多防蓝光的眼镜、防蓝光的手机膜、防蓝光的平板,这些材料和设备到底有没有用?如何正确预防蓝光危害呢? 我们现在所用的灯…...
BERT 快速理解——思路简单描述
定义: BERT(Bidirectional Encoder Representations from Transformers)是一种预训练的语言模型,它基于Transformer架构,通过在大规模的未标记文本上进行训练来学习通用的语言表示。 输入 在BERT中,输入…...
二叉树实现的相关函数
1.二叉树的创建 BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi) { if (n0||a[*pi] #){ (*pi);return NULL;}BTNode* root (BTNode*)malloc(sizeof(BTNode));root->_data a[(*pi)];root->_left BinaryTreeCreate(a, --n, pi);root->_right Binary…...
Redis面试题(二)
文章目录 前言一、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?二、Redis 和 Redisson 有什么关系?三、Jedis 与 Redisson 对比有什么优缺点?四、说说 Redis 哈希槽的概念?五、Redis 集群的主从复制模型是怎样的…...
STP介绍
目录 STP概述 二层环路带来的问题 1.广播风暴 2.MAC地址漂移问题 3.多帧复制---这个好理解,同一个数据帧被重复收到多次,被称为多帧复制。 802.1D生成树 STP的BPDU BPDU主要分为两大类 配置BPDU RPC COST 配置BPDU的工作过程 TCN BPDU TCN…...
numpy 和 tensorflow 中的各种乘法(点乘和矩阵乘)
嗨喽,大家好呀~这里是爱看美女的茜茜呐 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了,直接在文末名片自取就可 点乘和矩阵乘…...
(图论) 1020. 飞地的数量 ——【Leetcode每日一题】
❓ 1020. 飞地的数量 难度:中等 给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个 海洋单元格、1 表示一个 陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边…...
c++ 重载、重写、覆盖
重载:指在同一作用域内,有多个同名但参数不同的函数的现象,叫重载;可以是任何用户定义的函数,例如 类成员函数、类静态函数、普通函数重写:子类重写父类的同名函数,只要子类出现有父类的同名函数…...
Python异步编程高并发执行爬虫采集,用回调函数解析响应
一、问题:当发送API请求,读写数据库任务较重时,程序运行效率急剧下降。 异步技术是Python编程中对提升性能非常重要的一项技术。在实际应用,经常面临对外发送网络请求,调用外部接口,或者不断更新数据库或文…...
SpriteKit与Swift配合:打造您的第一个简易RPG游戏的步骤指南
1. 简介: RPG(Role-Playing Game)游戏是一种角色扮演游戏,它允许玩家在一个虚拟的游戏世界中扮演一个或多个角色。在本教程中,我们将使用Apple的2D游戏框架SpriteKit和Swift编程语言来创建一个简单的RPG游戏。我们将从…...
服务网格的面临挑战:探讨服务网格实施中可能遇到的问题和解决方案
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
