Rust结构体

结构体

Rust 中的结构体与其他语言中的定义一样,这是一种自定义的数据类型,用来组织多个相关的值,这些被放在结构体里的值就被称为字段(field),当然按以前的习惯还是叫成员变量更顺嘴。Rust 中结构体的成员变量都默认是私有的,想要设为公有可以使用pub关键字。

定义了结构体后,使用它需要为每个字段指定具体值来创建这个实例。创建一个实例时需要以结构体的名字开头,接着在大括号中使用 key: value 键 - 值对的形式提供字段,key 就是成员变量的名字,value 是设置给成员变量的值。

实例中成员变量的顺序不需要和它们在结构体中声明的顺序一致。使用成员变量的方法也和C系一样,使用 . 运算符。如果想要修改结构体中某个成员变量的值,也可以通过 . 取到之后直接赋值,但是,可以修改成员变量的前提是实例对象是可变的也就是创建实例时需要加 mut 关键字,此时整个结构体的所有成员变量都会是可修改的,Rust 中无法单独指定某个或某几个成员变量可变。
参考代码如下:

struct Student
{name: String,id: i32,chinese: i32,math: i32,english: i32,
}fn create_student() -> Student 
{Student {name: String::from("zhangsan"),id: 0,chinese: 30,math: 20,english: 10,}
}fn main()
{println!("hello world");let zs = create_student();println!("{} 的成绩为 Chinese: {}, Math: {}, English: {}", zs.name, zs.chinese, zs.math, zs.english);
}

这段代码中,我先定义了一个 student 结构体,然后写了一个函数 create_student 返回一个 student 对象; 最后在 main 函数中调用这个函数并输出返回对象的一些成员变量。
我试着让 create_student 返回一个 mut 对象,但是失败了,会有各种错误,然后查了一下,发现似乎在Rust中,方法不能直接返回一个可变对象。因为Rust的设计原则之一是不可变性(Immutability),它鼓励开发者编写安全、并发和高效的代码。如果一个方法返回一个可变对象,那么调用者可能会意外地修改这个对象,从而导致不可预测的行为和潜在的错误。如果要返回可能需要通过 new 的方式,但这部分还没看到,后续看到再补充。

**另外 Rust 的结构体本身不能定义方法,只能通过关联函数的方式为结构体赋予行为!**这也是 Rust 结构体和C++中最大的区别,Rust 的结构体只是一段数据,而不是像C++或者Java中的对象那样的概念。
关联方法的定义首先需要用 impl 关键字指明当前方法所关联的结构体,然后使用 fn + 名称 声明定义,可以拥有参数和返回值, 在同一个 impl 下可以有多个方法。关联方法还可以指定第一个参数为 self,这代表了调用当前方法的结构体实例。例如,给之前的 Student 添加一个计算总分的方法:

struct Student
{name: String,id: i32,chinese: i32,math: i32,english: i32,
}impl Student {fn total_cores(&self) -> i32 {self.chinese + self.math + self.english}
}fn create_student() -> Student 
{Student {name: String::from("zhangsan"),id: 0,chinese: 30,math: 20,english: 10,}
}fn main()
{println!("hello world");let zs = create_student();println!("{} 的成绩为 Chinese: {}, Math: {}, English: {}", zs.name, zs.chinese, zs.math, zs.english);println!("总成绩为: {}", zs.total_cores());
}

最终输出结果为:
在这里插入图片描述

impl 下定义的方法的第一个参数也可以不是 self,但是这样这个方法便不是与当前结构体关联的了,和一个普通定义的函数没区别。不过这种关联函数经常被用作返回一个结构体新实例的构造函数,这种函数的名称也通常为 new ,不过 new 并不是一个关键字。这样就可以将刚才的 create_student 封装进 impl 里面了, 并且返回值类型可以直接写为 self 。

另外定义的方法还可以与成员变量同名,当一个结构体存在同名的成员变量与方法时编译器在检测时如果在调用这个名的后面加上括号时,就认为调用的是方法,当未加括号则认为调用的是成员变量。当前Rust开发中大多数情况下与字段同名的方法都将被定义为只返回字段中的值,而不做其他事情。一般这样的方法在其他语言中被定义为 get ,主要作用就是保持成员变量的私密性。代码示例:

struct Student
{name: String,id: i32,chinese: i32,math: i32,english: i32,
}impl Student {fn total_cores(&self) -> i32 {self.chinese + self.math + self.english}fn create_student() -> Self {Student {name: String::from("zhangsan"),id: 0,chinese: 30,math: 20,english: 10,}}fn chinese(&self) -> i32 {return self.chinese;}
}fn main()
{println!("hello world");let zs = Student::create_student();println!("{} 的成绩为 Chinese: {}, Math: {}, English: {}", zs.name, zs.chinese(), zs.math, zs.english);println!("总成绩为: {}", zs.total_cores());
}

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

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

相关文章

看得懂的——数据库中的“除”操作

通过一个例子来解释数据库中的“除”操作 R➗S其实就是判断关系R中X各个值的象集Y是否包含关系S中属性Y的所有值 求解步骤 第一步 找出关系R和关系S中相同的属性,即Y属性。在关系S中对Y做投影(即将Y列取出);所得结果如下&#x…

众和策略:跨界收购算力公司 高新发展斩获3连板

高新展开23日开盘再度一字涨停,截至发稿,该股报21.74元,涨停板上封单超200万手。至此,该股已连续3个生意日涨停。 公司18日晚间宣布生意预案,拟通过发行股份及支付现金的方式购买高投电子集团持有的华鲲振宇30%股权、…

医院智能电力系统解决方案

摘要:智能电力系统主要体现在“智能”,在医院中智能电力系统主要以数字电力系统为主,它主要表现为信息化、自动化。通过对数据的采集分析,以及反馈传输运行。其中医院智能电力系统优点在于,(1)通过医院的生产数据&…

python免杀初探

文章目录 loader基础知识loader参数介绍 evilhiding项目地址免杀方式修改加载器花指令混淆loader源码修改签名加壳远程条件触发修改ico的md5加密 loader基础知识 loader import ctypes #(kali生成payload存放位置) shellcode bytearray(b"shellc…

CSS3属性详解(一)文本 盒模型中的 box-ssize 属性 处理兼容性问题:私有前缀 边框 背景属性 渐变 前端开发入门笔记(七)

CSS3是用于为HTML文档添加样式和布局的最新版本的层叠样式表(Cascading Style Sheets)。下面是一些常用的CSS3属性及其详细解释: border-radius:设置元素的边框圆角的半径。可以使用四个值设置四个不同的圆角半径,也可…

自然语言处理---RNN经典案例之使用seq2seq实现英译法

1 seq2seq介绍 1.1 seq2seq模型架构 seq2seq模型架构分析: seq2seq模型架构,包括两部分分别是encoder(编码器)和decoder(解码器),编码器和解码器的内部实现都使用了GRU模型,这里它要完成的是一个中文到英文的翻译:欢迎…

设计模式:策略模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

简介: 策略模式,它是一种行为型设计模式,它定义了算法族,分别封装起来,让它们之间可以互相替换。策略模式让算法的变化独立于使用算法的客户,降低了耦合,增加了系统的可维护性和可扩展性。 策…

AI的Prompt是什么

一.AI的Prompt的作用 在人工智能(AI)中,"Prompt"通常指的是向AI系统提供的输入或指令,用于引导AI进行特定的操作或生成特定的输出。例如,在一个对话型AI系统中,用户输入的问题就是一个prompt&…

使用 VS 2022 开发C#项目的tips

代码操作 删除注释或空行 参考C#【必备技能篇】Visual Studio删除所有的注释和空行 删除所有行注释:包括行内和行外,如下所示 Ctrl H 替换,第一行输入://[^\n]*\n, 第二行输入:\n。替换即可。 这一步可能出现很多空…

C#上位机序列9: 批量读写+事件广播+数据类型处理

一、源码结构: 二、运行效果: 三、源码解析 1. 读取配置文件及创建变量信息(点位名称,地址,数据类型(bool/short/int/float/long/double)) 2. 异步任务处理:读任务&…

组态软件和人机界面与plc之间Profinet无线通讯

在实际应用中,车间里分布的多台PLC,会由一台触摸屏集中控制,同时用户也许要将PLC数据共享给总控的上位机软件进行数据监控。此时需要实现,PLC、触摸屏、上位机之间的数据实时共享功能。在有通讯需求的时候,如果布线的话…

正规文法、正规式、确定的有穷自动机DFA、不确定的有穷自动机NFA 的概念、区分以及等价性转换【我直接拿下!】

文章目录 正规文法正规式有穷自动机确定的有穷自动机——DFA不确定的有穷自动机——NFADFA 与 NFA 的区分 正规式转换为正规文法正规文法转换为正规式NFA 转换为 DFANFA 最小化 NFA 转换为正规式正规式转换为 NFA正规文法转换为 NFANFA 转换为正规文法 前言: 在学习…

每日一题 2316. 统计无向图中无法互相到达点对数(中等,图连通分量)

题目很简单,只要求出每个连通分量有多少个节点即可首先通过建立一个字典来表示每个节点的邻接关系遍历每个节点,并通过邻接关系标记在当前连通分量内的所有的点,这样就可以知道一个连通分量内有多少个点在这里我陷入了一个误区,导…

NET7下用WebSocket做简易聊天室

NET7下用WebSocket做简易聊天室 步骤: 建立NET7的MVC视图模型控制器项目创建websocket之间通信的JSON字符串对应的实体类一个房间用同一个Websocketwebsocket集合类,N个房间创建websocket中间件代码Program.cs中的核心代码,使用Websocket聊…

【Linux】32条指令带你玩转 Linux !

目录 1,whoami 2,who 3,pwd 4,ls 1,ls 2,ls -l 3,ls -a 4,ls -al 5,ls -d 6,ls -ld 5,clear 6,cd 1,cd 2&…

老胡的周刊(第112期)

老胡的信息周刊[1],记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 🎯 项目 LocalAI[2] 🤖 免费、开源的 Ope…

分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测

分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.分类预测 | MATLAB实现基于LSTM-Ada…

强化学习问题(7)--- Python和Pytorch,Tensorflow的版本对应

1.问题 之前下载的python3.8,在对应Pytorch和Tensorflow时没太在意版本,在运行一些代码时,提示Pytorch和Tensorflow版本过高,直接降下来,有时候又和Python3.8不兼容,所以又在虚拟环境搞一个Pyhon3.7&#x…

数字秒表verilog电子秒表跑表,代码/视频

名称:数字秒表verilog电子秒表跑表 软件:Quartus 语言:Verilog 代码功能: 设计电子秒表,秒表时间精确到0.01秒,可通过按键控制秒表启动、暂停、复位。 代码需要在Mini_Star开发板验证。 开发板资料&…

逐秒追加带序号输入当前时间:fgets fputs sprintf fprintf

//向某文件中逐秒追加带序号输入当前时间 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> #include <unistd.h> int main(int argc, char const *argv[]) { time_t tv; // time(&tv);//法1:获取秒数 …