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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity 动画系统

动画系统包含: 动画片段 Animation Clip,记录物体变化的信息,可以是角色的闪转腾挪,也可以是一扇门的开闭动画状态机 Animator Controller,根据设置切换动画片段动画组件 Animator,Animation替身 Avatar&a…

数据结构基础8:二叉树oj+层序遍历。

二叉树oj层序遍历 题目一:二叉树的销毁:方法一:前序遍历:方法二:后序遍历: 题目二:二叉树查找值为x的节点方法一:方法二:方法三: 题目三:层序遍历…

Python 和 MatLab 模拟粒子动力系统

力计算 我们将假设一个由 N N N 个点粒子组成的系统,索引为 i 1 , … , N i1, \ldots, N i1,…,N。每个粒子都有一个: 质量 m i m_i mi​ 位置 r i [ x i , y i , z i ] r_{\boldsymbol{i}}\left[x_i, y_i, z_i\right] ri​[xi​,yi​,zi​] 速…

透视俄乌网络战之二:Conti勒索软件集团(下)

透视俄乌网络战之一:数据擦除软件 透视俄乌网络战之二:Conti勒索软件集团(上) Conti勒索软件集团(下) 1. 管理面板源代码2. Pony凭证窃取恶意软件3. TTPs4. Conti Locker v2源代码5. Conti团伙培训材料6. T…

【Linux从入门到精通】多线程 | 线程互斥(互斥锁)

上篇文章我们对线程 | 线程介绍&线程控制介绍后,本篇文章将会对多线程中的线程互斥与互斥锁的概念进行详解。同时结合实际例子解释了可重入与不被重入函数、临界资源与临界区和原子性的概念。希望本篇文章会对你有所帮助。 文章目录 引入 一、重入与临界 1、1 可…

ffmpeg 特效 转场 放大缩小

案例 ffmpeg \ -i input.mp4 \ -i image1.png \ -i image2.png \ -filter_complex \ [1:v]scale100:100[img1]; \ [2:v]scale1280:720[img2]; \ [0:v][img1]overlay(main_w-overlay_w)/2:(main_h-overlay_h)/2[bkg];\ [bkg][img2]overlay0:0 \ -y output.mp4 -i input.mp4//这…

多线程|多进程|高并发网络编程

一.多进程并发服务器 多进程并发服务器是一种经典的服务器架构,它通过创建多个子进程来处理客户端连接,从而实现并发处理多个客户端请求的能力。 概念: 服务器启动时,创建主进程,并绑定监听端口。当有客户端连接请求…

GitLab使用的最简便方式

GitLab介绍 GitLab是一个基于Git版本控制系统的开源平台,用于代码托管,持续集成,以及协作开发。它提供了一套完整的工具,以帮助开发团队协同工作、管理和部署代码。 往往在企业内部使用gitlab管理代码,记录一下将本地代…

VR航天航空巡展VR科技馆航天主题科普设备沉浸遨游太空

每当飞机飞过头顶,我们总是忍不住抬头去仰望。从嫦娥奔月的神话传说,到莱特兄弟实现了上天翱翔的梦想,人类一直在不断探索更辽阔的天空和浩瀚的宇宙。 航空科普 寻梦而行 普乐蛙VR航天航空巡展,正在湖南郴州如火如荼的进行中&…

arm day2(9.15)数据操作指令,跳转指令,特殊功能寄存器指令,

作业 1.求最大公约数&#xff1a; .text .global _start _start:mov r0,#0x9mov r1,#0x15bl Loop Loop:cmp r0,r1 比较r0寄存器和r1寄存器的中的值beq stop 当两数相同时,退出程序subhi r0,r0,r1 r0>r1 r0 r0 - r1subcc r1,r1,r0 r0<r1 r1 r1 - r0mov pc,lr 恢复现…

【算法与数据结构】108、LeetCode将有序数组转换为二叉搜索树

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;这道题给我们的是一个有序数组&#xff0c;并要求构成一个平衡二叉搜索树&#xff0c;二叉搜索树的很容…

CSS 之 grid 网格布局

一、简介 ​ display: grid;用于设置元素内部的布局类型为网格布局&#xff0c;其外显类型为块级元素。该类型的元素将内部分为行和列&#xff0c;划分成一个个单元格&#xff0c;并通过一系列相关属性控制单元格及其内容的布局和大小。 ​ 该属性值的主要应用场景为&#xf…

这个锂电池保护方案来自TIDA-010030

本篇博客只是作为个人记录&#xff0c;拆锂电池有危险&#xff0c;撬棒刺穿外壳可能爆炸&#xff0c;请勿模仿&#xff0c;误操作电池数据可能失效&#xff0c;请勿模仿。 1、简介 1.1、目的 得到该电池的电量计芯片型号、IIC从机地址、通信的实际波形&#xff1b; 1.2、步…

百度飞浆OCR识别表格入门python实践

1. 百度飞桨&#xff08;PaddlePaddle&#xff09; 百度飞桨&#xff08;PaddlePaddle&#xff09;是百度推出的一款深度学习平台&#xff0c;旨在为开发者提供强大的深度学习框架和工具。飞桨提供了包括OCR&#xff08;光学字符识别&#xff09;在内的多种功能&#xff0c;可…

Linux驱动IO篇——异步通知

文章目录 什么是异步通知异步通知和异步IO的区别信号含义应用层使用信号驱动如何实现异步信号驱动实例 什么是异步通知 异步通知在Linux的实现中是通过信号&#xff0c;而信号是在软件层次上对中断机制的一种模拟。这种机制和中断非常类似&#xff0c;所以可以以中断的思想来理…

go -- 获取当前24点的时间戳 --chatGpt

gpt: 要获取当前24点的时间戳&#xff0c;你可以使用 Go 标准库中的 time 包来实现。以下是一个示例函数&#xff0c;它可以获取当前日期的24点的时间戳&#xff1a; go package main import ( "fmt" "time" ) func getMidnightTimestamp() in…

重新认识交叉编译

1. 我以前对交叉编译的认知 引用正点原子的话来讲就是: 说得对&#xff0c;但是不全面&#xff0c;直到最近项目中遇到了一个例子我才重新认识什么是交叉编译。 2. build/host/target的概念 参考: Cross-Compilation (automake) 参考: Specifying Target Triplets (Autocon…

开源免费的流程图软件draw.io

2023年9月16日&#xff0c;周六上午 想买微软的visio&#xff0c;但发现不是很值得&#xff0c;因为我平时也不是经常需要画图。 所以我最后还是决定使用开源免费的draw.io来画图 draw.io网页版的网址&#xff1a; Flowchart Maker & Online Diagram Software draw.io的…

Python二级 每周练习题18

练习一: 从键盘输入任意字符串&#xff0c;按照下面要求分离字符串中的字符: 1、分别取出该字符串的第偶数位的元素(提醒注意:是按照从左往右数的方式确定字符串的位置) 2、并依次存储到一个列表中; 3、输出这个列表。 答案: ninput(请输入任意字符串:) #创建变量n存放用户…

数据结构入门 — 树的概念与结构

本文属于数据结构专栏文章&#xff0c;适合数据结构入门者学习&#xff0c;涵盖数据结构基础的知识和内容体系&#xff0c;文章在介绍数据结构时会配合上动图演示&#xff0c;方便初学者在学习数据结构时理解和学习&#xff0c;了解数据结构系列专栏点击下方链接。 博客主页&am…