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比较新,但是也没有说新到颠覆一切。合理看待。

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

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

相关文章

微信小程序商城构建全栈应用

今天&#xff0c;将之前大学朋友分享给我的好几个小程序内容&#xff0c;简单的从百度网盘下载了一下&#xff0c;重新回顾小程序内容&#xff0c;重新构建融合一些不同语言的元素。下面是网盘的简单截图。 我先挑选了一个微信小程序商城项目&#xff0c;简单看了看&#xff0…

中霖教育:不是会计专业能参加24年的中级会计师考试吗?

经常有很多同学问&#xff1a;我不是会计专业的能报中级会计师考试吗? 先来看报名需要满足的必要条件&#xff1a; 1、大学专科学历&#xff0c;从事会计工作满5年。 2、大学本科学历或学士学位&#xff0c;从事会计工作满4年。 3、第二学士学位或研究生班毕业&#xff0c…

Rust编程(三)生命周期与异常处理

生命周期 生命周期&#xff0c;简而言之就是引用的有效作用域。在大多数时候&#xff0c;我们无需手动的声明生命周期&#xff0c;因为编译器可以自动进行推导。生命周期的主要作用是避免悬垂引用&#xff0c;它会导致程序引用了本不该引用的数据&#xff1a; {let r;{let x …

Partisia Blockchain:真正做到兼顾隐私、高性能和可拓展的公链

目前&#xff0c;包括 Secret Network、Oasis Protocol 等在内的绝大多数以隐私为特性的可编程公链&#xff0c;在兼顾隐私的同时&#xff0c;在可拓展以及性能上或多或少的有所牺牲&#xff0c;即难以对诸多实际应用场景进行支撑。这归咎于链的设计以及共识机制的不合理&#…

袁志佳:前端全栈工程师精英班

教程介绍 本套课程涵盖大前端的全部领域&#xff0c;并对传统的Web前端全栈深入教学。如利用前端知识开发 AI、VR、AR、iOS、Android、PC、Server、智能硬件。 同时我们将核心打造 JavaScript语言新发展、Vue源码分析、前端持续集成方案汇总、MV*框架深度分析 、前端图形学、N…

Python爬虫如何快速入门

写了几篇网络爬虫的博文后&#xff0c;有网友留言问Python爬虫如何入门&#xff1f;今天就来了解一下什么是爬虫&#xff0c;如何快速的上手Python爬虫。 一、什么是网络爬虫 网络爬虫&#xff0c;英文名称为Web Crawler或Spider&#xff0c;是一种通过程序在互联网上自动获取…

目前2024年腾讯云4核8G服务器租用优惠价格表

2024年腾讯云4核8G服务器租用优惠价格&#xff1a;轻量应用服务器4核8G12M带宽646元15个月&#xff0c;CVM云服务器S5实例优惠价格1437.24元买一年送3个月&#xff0c;腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器优惠价格 轻…

虚拟机如何在原有磁盘上扩容

虚拟机未开启状态–菜单栏–虚拟机–快照–拍摄快照–拍摄快照– 菜单栏–虚拟机–快照–快照管理器–点击刚刚的快照1–删除–是– 文件–新建或者打开–硬盘&#xff08;以本人Win 10.64.3GL为例&#xff09;–虚拟机设置–硬件– 硬盘&#xff08;SATA&#xff09;–磁盘实…

Git基础(24):分支回退

文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中&#xff0c;可能开发某个功能不需要了&#xff0c;或者想要回退到之前历史的某个commit&#xff0c; 放弃后来修改的内容。 放弃已修改的内容 如果未提交&#xff0c;直接使用 …

二分算法的变种----查找递增可重复数组边界

public class test {//数组长度a,b,c为8,d为7&#xff1b;static int[] a {3,5,8,8,8,9,9,10};static int[] b {8,8,8,8,8,8,8,8};static int[] c {0,0,0,0,0,0,0,0};static int[] d {0,0,0,0,0,0,0};public static void main(String[] args) {int target 0;System.out.pr…

Windows下pycharm配置QtDesigner、PyUic、PyRcc

前言&#xff1a; 在配置QtDesigner、PyUic、PyRcc之前&#xff0c;咱们先了解一下这三个工具在PyQt5里面的作用 Qt Designer、PyUIC、PyRCC 在 PyQt5 开发中扮演着重要的角色&#xff0c;它们分别用于设计界面、将设计的界面转换为 Python 代码以及管理资源文件。下面将详细解…

Python性能测试框架Locust实战教程

01、认识Locust Locust是一个比较容易上手的分布式用户负载测试工具。它旨在对网站&#xff08;或其他系统&#xff09;进行负载测试&#xff0c;并确定系统可以处理多少个并发用户&#xff0c;Locust 在英文中是 蝗虫 的意思&#xff1a;作者的想法是在测试期间&#xff0c;放…

使用IDEA的反编译插件 反编译jar包

反编译插件介绍 安装IDEA后, 一般自带反编译插件, Java Bytecode Decompiler 如果没有可以自己安装下 1.首先找到插件的jar包, 在IDEA安装目录的plugins文件夹下 D:\IntelliJ IDEA 2021.2.2\plugins\java-decompiler\lib 2.运行java命令, 指定插件的jar包目录和你要反编译的ja…

C语言从入门到实战----数据在内存中的存储

1. 整数在内存中的存储 在讲解操作符的时候&#xff0c;我们就讲过了下⾯的内容&#xff1a; 整数的2进制表⽰⽅法有三种&#xff0c;即 原码、反码和补码 有符号的整数&#xff0c;三种表⽰⽅法均有符号位和数值位两部分&#xff0c;符号位都是⽤0表⽰“正”&#xff0c;⽤…

【C++】用哈希桶模拟实现unordered_set和unordered_map

目录 一、哈希介绍1.1 哈希概念1.2 哈希冲突解决1.2.1 闭散列1.2.2 开散列 二、哈希桶2.1 实现哈希桶2.1.1 构造节点和声明成员变量2.1.2 构造与析构2.1.3 仿函数2.1.4 查找2.1.5 插入2.1.6 删除 2.2 kv模型哈希桶源代码 三、改造哈希桶3.1 beginend3.2 迭代器3.2.1 前置 3.3 改…

【C语言进阶篇】编译和链接

【C语言进阶篇】编译和链接 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C语言&#x1f353; &#x1f33c;文章目录&#x1f33c; 编译环境与运行环境 1. 翻译环境 2. 编译环境&#xff1a;预编译&#xff08;预处理&#xff09;编…

动态规划标题

题目&#xff1a;猫粮规划 每种食物都有两种状态&#xff0c;记忆化dfs当然可以&#xff0c;但是你是否觉得这个题很想之前讲过的“小A点菜 ”&#xff1f;那道题问的是对于那些菜要花光她的钱&#xff0c;一共有多少方案&#xff1f;这道题问的是一个区间罢了&#xff0c;那么…

Swagger3探索之游龙入海

引言 后端开发中常用的接口调用工具一般使用Postman、ApiPost工具&#xff0c;但后期需要与前端联调&#xff0c;要补充接口文档花费大量时间&#xff0c;此时Swagger3应运而生&#xff0c;大大提高沟通交流的效率。 引用依赖 <!-- Swagger3 调用方式 http://ip:port/swa…

已后悔!为什么不早点用多微信管理工具?

对于有多个微信号的人来说&#xff0c;每次都要在不同微信号和设备之间来回切换&#xff0c;实在是既麻烦又容易搞混。 这时候&#xff0c;只需要一个多微信管理工具——微信管理系统就能解决啦&#xff01; 1、多号同时登陆聚合聊天 它支持多个微信号同时登录在同一个页面上…

【已解决】Vue 3+TS项目,无法找到模块“XXX”的声明文件,项目报错无法找到声明文件

前言 最近在做vue 3 TS项目&#xff0c;创建项目时需要引入vue-router 4&#xff0c;在main根文件中引入路由时出现了无法找到引入文件的报错。 解决 最后发现是创建router文件中的index文件时错误的创建为了.js文件&#xff0c;但是在创建框架时默认使用的是TS。将文件类型…