Rust编程(二)语法和数据类型

编程规范

类C语法,函数需要定义,指令需要以;结尾。需要大括号{}
文件名,变量,函数命名使用snake case,eg:new_function()
结构体,特征命名,使用大驼峰命名,eg:Student,ChangeInfo

数据类型

Rust 是 静态类型(statically typed)语言,每个数据都必须声明类型,数据的初始化方式为let a : Type = value;

let a : i32 = 6;
let b : f32 = 6.0;
let c : char = '6';
let d : [i32;6] = [1,2,3,4,5,6]
let e : (char,i32) = ('6',6);
let f : Vec<i32> = Vec::new();

Rust中的变量默认是不可变的,如果想要可变,需要添加mut关键字:

let mut g: i32 = 1;

基本标量:

  • 整型:i32
  • 浮点型:f32
  • 布尔类型:bool
  • 字符类型:char
    复合数据类型:
  • 原生数组:[i32;5]
  • 元组:(i32,i32,i8)
  • 【Rust 标准库提供】可变数组:Vec
  • Sring,字符串
  • &str:字符串面值,可以理解为,“abc”就是字符串面值,跟其他语言一样不可更改,而String则是另一种字符串,他可以修改,可以添加,删除,替换等等,跟C++的String别无二样。

所有权

Rust通过控制所有权来实现内存管理
Rust中所有的变量都是有所有权的,变量的初始化被称为变量绑定,即将这个数据绑定到这个变量上。
Rust对于简单基本数据类型,会直接进行拷贝,不会考虑所有权问题,但是对于复杂数据类型,就有所有权制度了,如下

let s1 = Stinrg::from("name");
let s2 : String;
s2 = s1;
println!("{}",s1);
//这种情况就会报错,因为Rust中,对于复杂数据类型,等于号默认就是所有权的交接,
//此时数据的所有权已经从s1转移到s2了,这种称为move
//也就是说,Rust中默认的=是move而不是浅拷贝
//Rust中有一个特征是Copy,实现了Copy特征的,都是拷贝而不是move,
//官方给出的可以Copy的类型规则:任何基本类型的组合可以 Copy ,不需要分配内存或某种形式资源的类型是可以 Copy 的。

请添加图片描述
Rust中的函数传参也适用所有权制度:

let s3 = String::from("value");
a_function(s3) 
//此时s3数据的所有权已经move给函数了,
//在函数调用结束时,如果所有权不传出来,那么Rust就会自动调用drop清理掉相应数据的内存。

所有权传来传去很麻烦,所以就设计了引用和借用机制:

let x: i32 = 1;
let y = &x;

println!("{},{}",x,*y);
//引用机制,直接指向同一个地址

请添加图片描述
引用,一个指针指向了原数据类型,只能看不能改。

还记得前面说的可变与不可变性吗?如果想要获得修改权,就需要借用,引用只能看不能改。

let x: i32 = 1;
let temp = &x; //引用,一旦引用了,原数据就不能再被借用了,确保在引用期间数据不会改变。
let y = &mut x; //借用,把上面的那句引用注释掉就可以借用了
*y = 6; //借用,可以修改
println!("The value of y is: {}", y);
println!("The value of x is: {}", x); //会报错,此时x处于被借用状态,自己没法用
let y = 1; //给y绑定一个新的值,把原本的y覆盖掉
println!("The value of x is: {}", x); //此时就又可以用了,而且值也已经修改了。
//其实不覆盖也可以,因为Rust检测到后面y不用了就会自动把借用还回去,可以把let y = 1注释掉,依旧可以。

其实所有权,引用和借用的机制很简单,就是把数据和变量分开了,变量是数据的所有者,所有权就是指把数据分配给这个变量了。
转移所有权就是指把这个数据转移给另一个变量,原变量就go die了。
引用就是指可以看这份数据但是不能改,而且数据的所有者不能再把数据借给其他变量。
借用就是指将数据暂时借给其他变量,在借给其他变量后,原变量就像个植物人一样,啥也不能干,但是借用一旦归还,就又活过来了。

控制流

常见if-else,for,while,该有的都有

函数

fn function(inputvalue:input_type,inputvalue2:input_type2) -> return_type {
	println!("This is a function");
	let result: return_type = value;
	return result;
}

结构体

Rust中没有类的概念,取而代之的是跟C一样的struct,struct不能继承,早期的Rust有virtual struct,是可以继承的,后面删除了,不能使用继承了。Rust实现多态的方式是使用特征trait。

封装继承,多态,是面向对象编程的三个特征,这是目前最常见的说法。不过我们跳出这三个特征来谈OOP(面向对象),我们会发现,其实面向对象的主要思想就类似于状态机一样,对象就是状态的封装,通过行为来不断改变状态,最终得到结果,而多态是为了实现同一个行为可以应对复用在多个状态机上。从这个角度出发,我们就不难理解为什么Rust要这么设计了,Rust认为要实现多态不一定非要使用继承,继承反而会破坏掉封装,我们的目的只是要复用行为,没必要把状态机之间扯上关系,所以,Rust将状态和行为分开封装,状态封装为了struct,行为封装成了方法,而想要在多个状态上复用的行为,封装成了特征,struct不需要知道自己和哪个struct共用特征,只需要实现相应的特征即可,特征在特定的上下文也可以识别出自己接受的struct类型,达到和继承一样的效果。不过Rust官方并不称为自己是面向对象语言,虽然可以用OOP的方法来编程,但是会跟所有权等机制格格不入。

struct Person{
	name : String,
	age : i32,
	address : String,
}

方法

跟传统OOP中的成员函数一样。

impl Person{
	fn change_name(&mut self,new_name) -> (){
		self.name = new_name;
	}
}

特征trait

trait是Rust中独有的一种机制,有点像接口类的概念,如果不同的类型具有相同的行为,那么我们就可以定义一个特征,然后为这些类型实现该特征。定义特征是把一些方法组合在一起,目的是定义一个实现某些目标所必需的行为的集合。
如下,我们定义了一个特征,名称为ChangeInfo,所有有该行为需求的类都可以实现一个该特征,例如Student和Teacher。

pub trait ChangeInfo{
    fn change_name(&mut self,new_name) -> (); //注意,这里是;不是{}
    fn init_all_info(&mut self) -> (){ //也可以设置默认实现,默认实现允许调用相同特征中的其他方法,哪怕这些方法没有默认实现。
    	self.change_name(String::new());
	}
}

struct Student{
	name: String,
}

impl ChangeInfo for Student{
	fn change_name(&mut self,new_name) -> (){
		self.naem = new_name;
	}
}

struct Teacher{
	name: String,
}

impl ChangeInfo for Teacher{
	fn change_name(&mut self,new_name) -> (){
		self.naem = new_name;
	}
}

fn main(){
	let student:Student = Student{
		name:String::new(),
	}
	student.init_all_info();
	student.change_name(String::from("Wang"));
	
}

还可以使用特征来作为参数:

pub fn function(item: &impl ChangeInfo) { //使用实现了ChangeInfo的类型作为参数
    item.init_all_info();
}

trait还有很多应用方法,具体可以看Rust圣经

泛型

Rust支持泛型编程,跟C++的泛型没有很大区别
Rust中的泛型也分为:函数泛型,结构体泛型
Rust中的泛型也可以进行模板特化,为某一种特殊的数据类型进行单独实现。
Rust在1.5以后也可以支持类似于C++参数模板的功能了。

fn display_array<T: std::fmt::Debug, const N: usize>(arr: [T; N]) {
//T是要实现了Debug特征的类型,N是一个const 泛型,是一个值
    println!("{:?}", arr);
}
fn main() {
    let arr: [i32; 3] = [1, 2, 3];
    display_array(arr);

    let arr: [i32; 2] = [1, 2];
    display_array(arr);
}

总结

Rust面向对象上与C++有理念上的不同,所以实现也有较大区别,但是在泛型上,跟C++区别不大。至于Rust所独有的所有权以及借用和引用,是为了实现内存安全和像C++一样的速度而设计的,如果依旧使用深拷贝和浅拷贝机制,不加以管理让用户自己选择拷贝策略或者像Python一样默认浅拷贝,会内存不安全。如果默认深拷贝,则会效率极低。

Python可以默认浅拷贝是因为有GC兜底,内存管理不依赖程序员。

所以,Rust比较新,但是也没有说新到颠覆一切。合理看待。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

舵机烧录

舵机烧录 一、硬件连接1、准备物资2、连接&#xff08;1&#xff09;舵机线一侧连接舵机控制板&#xff0c;另一侧连接舵机&#xff08;2&#xff09;老安卓线一侧连接舵机控制板&#xff0c;一侧连接电脑&#xff08;3&#xff09;接上低压电池 二、软件使用1、打开舵机烧录软…

JavaScript高架(二)-V8引擎下

书归上回 ECS&#xff08;Execution Context Stack&#xff09; V8引擎为了执行代码, V8引擎内部会有一个执行上下文栈Execution Context Stack&#xff08;ESC函数调用栈)&#xff0c;当首次加载JS的时候就会创建一个Execution Context Stack(ECS)&#xff0c;它是用于执行代…

前端面试题---->JavaScript

const声明的对象属性和数组的值可以被修改吗&#xff1f;为什么 原因&#xff1a;当使用const声明一个对象或数组时&#xff0c;实际上是保证了对象或数组的引用不会被修改&#xff0c;但对象或数组本身的属性或元素是可以被修改的。这是因为const只能保证指向的内存地址不变&a…

ChatGPT赋能大气科学:GPT与Python结合应用遥感降水数据处理、ERA5大气再分析数据的统计分析、干旱监测及风能和太阳能资源评估等

目录 专题一 AI领域常见工具讲解 专题二 POE平台及ChatGPT使用方法 专题三 提示词工程 专题四 科研常见应用场景 专题五 Python简明教程 专题六 GPT科研绘图 专题七 GPT辅助下载数据 专题八 遥感降水数据 专题九 数据产品评估 专题十 ERA5全球大气再分析数据 专题十…

python和Vue开发的RBAC用户角色权限管理系统

后端框架&#xff1a;python的FastAPI作为后端服务和python-jose作为JWT认证 前端框架&#xff1a;Vue3构建页面和Vue Router作为路由管理&#xff0c;Pinia作为数据存储&#xff0c;Vite作为打包工具 可以实现菜单控制和路由控制&#xff0c;页面里面有按钮权限控制&#xf…

【深度学习|基础算法】2.AlexNet学习记录

AlexNet示例代码与解析 1、前言2、模型tips3、模型架构4、模型代码backbonetrainpredict 1、前言 AlexNet由Hinton和他的学生Alex Krizhevsky设计&#xff0c;模型名字来源于论文第一作者的姓名Alex。该模型以很大的优势获得了2012年ISLVRC竞赛的冠军网络&#xff0c;分类准确率…

【无标题】C高级325

练习1&#xff1a;输入一个数&#xff0c;实现倒叙123-》321 练习2&#xff1a;输入一个&#xff0c;判断是否是素数 练习3&#xff1a;输入一个文件名&#xff0c; 判断是否在家目录下存在, 如果是一个目录&#xff0c;则直接输出是目录下的sh文件的个数 如果存在则判断是否是…

spring cloud 限流熔断配置

springcloud 微服务网关 zuul.strip-prefixtrue zuul.routes.postgres-client.path /ps01/** zuul.routes.postgres-client.service-idpostgres-client zuul.routes.postgres-client02.path/ps02/** zuul.routes.postgres-client02.service-idpostgres-client02 zuul.semaphor…

密码学之哈希碰撞和生日悖论

哈希碰撞 哈希碰撞是指找到两个不一样的值&#xff0c;它们的哈希值却相同 假设哈希函数的取值空间大小为k &#xff0c;计算次数为n 先算每个值不一样的概率P’ 所以至少两个值相同(即存在哈希碰撞)的概率P为 生日悖论 假设班里有50个人&#xff0c;求班里至少两个人相同…

亚信安慧AntDB:轻松解决数据处理挑战

AntDB一直秉承着“技术生态”的理念&#xff0c;不断进行技术创新和功能增强&#xff0c;以保持与先进数据库系统的竞争力。作为一款致力于提升数据库处理性能和稳定性的系统&#xff0c;AntDB在技术上始终保持敏锐的洞察力&#xff0c;不断汲取国内外先进技术的精华&#xff0…

【C语言】Infiniband驱动__mlx4_init_one函数

一、注释 Linux内核驱动程序中的部分&#xff0c;属于Mellanox网卡驱动mlx4的初始化过程。 // Mellanox 以太网驱动主程序代码 static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,struct mlx4_priv *priv) {int err; // 错误码变量int nvfs[MLX4_MAX_PORTS…

【vue3学习笔记(二)】(第141-143节)初识setup;ref函数_处理基本类型;ref函数_处理对象类型

尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 本篇内容对应课程第141-143节 课程 P141节 《初识setup》笔记 1、setup是所有组合式API“表演的舞台”&#xff0c;组件中所用到的所有数据、方法、监视数据、生命周期钩子等都需要配置在setup中。 2、setup的两种返回值&…

【MySQL】4.MySQL日志管理与数据库的备份和恢复

备份的目的只要是为了灾难恢复&#xff0c;备份还可以测试应用&#xff0c;回滚数据&#xff0c;修改和查询历史数据&#xff0c;审计等 日志在备份、恢复中起着重要作用 一、数据库备份的重要性 在生产环境中&#xff0c;数据的安全性至关重要 任何数据丢失都可能产生严重的…

数组的常见算法

数组的常见算法 数值型数组特征值统计 这里的特征值涉及到&#xff1a;平均值、最大值、最小值、总和等 举例1&#xff1a;数组统计&#xff1a;求总和、均值 public class TestArrayElementSum {public static void main(String[] args) {int[] arr {4,5,6,1,9};//求总和、…

Android 性能优化实例分享-内存优化 兼顾效率与性能

背景 项目上线一段时间后,回顾重要页面 保证更好用户体验及生产效率&#xff0c;做了内存优化和下载导出优化&#xff0c;具体效果如最后的一节的表格所示。 下面针对拍摄流程的两个页面 预览页 导出页优化实例进行介绍&#xff1a; 一.拍摄前预览页面优化 预览效果问题 存在…

实时通讯技术实现

实时通讯技术实现 前言 在CS架构中&#xff0c;经常会有实时通信的需求。客户端和服务端建立连接&#xff0c;服务端实时推送数据给客户端。本文介绍几种常见的实现方式&#xff0c;希望能给读者们一点点参考。 实时通讯的主要实现技术 长轮询(Long Polling) WebSocket 服务器发…

搜索(find a way, Pots)

Find a way 思路&#xff1a;这一题看似简单其实不然&#xff0c;有很多特办条件&#xff0c;如果当这个M和Y都在KFC的时候就会导致步数为0 &#xff0c;或者可以这样说&#xff1a;只有两人都能到达才能算入答案。 我们可以使用bfs来写这道题&#xff0c;这不过这道题目不需…

ChatGPT,来一份3·28雷布斯米时捷上市发布会即时发言稿

你新招了一个秘书。上班第一天&#xff0c;你对他说&#xff1a;“3月28号我可能会受邀参加雷老板的米时捷’上市发布会&#xff0c;届时我可能会有十分钟的发言机会&#xff0c;你现在准备一篇演讲稿。” 秘书问你有何指导意见&#xff1f; 你自己都不知说啥子&#xff0c;能…

探秘 RabbitMQ 的设计理念与核心技术要点

目录 一、消息中间件介绍 1.1 消息中间件的作用 二、RabbitMQ 2.1 核心概念 2.2 生产者发送消息过程 2.3 消费者接收消息过程 2.4 RabbitMQ 为何要引入信道(channel) 2.5 消费模式 一、消息中间件介绍 消息队列中间件&#xff08;message queue middleWare, MQ&#xff09;指…

前端发版上线出现白屏问题

目录 路由配置问题资源缓存问题首屏加载过慢 &#xff1a;喂&#xff0c;你的页面白啦&#xff01; 出现上线白屏的问题有很多&#xff0c;如&#xff1a;配置错误、缓存问题、浏览器兼容问题&#xff0c;根据不同情况去解决。 路由配置问题 问题描述&#xff1a; 在vue开发…