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…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
