Rust - 安装环境、基本类型、流程控制、函数、模块、泛型、所有权
安装环境、基本类型
学习Rust语言是公司同事最先开始提议的,准备用接下来的项目试试水,Rust是一个强类型编译型语言,比较偏向底层,所以开启了Rust的探索之旅。
环境准备阶段
安装Rust环境
安装命令:
(相关资料图)
curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | shsource $HOME/.cargo/env //设置环境变量rustc --version //查看安装版本Cargo
Cargo 是 Rust 的构建系统和包管理器。Rust 开发者常用 Cargo 来管理 Rust 工程和获取工程所依赖的库。
Cargo 就是Vue里面的npm,php里的composer。
cargo run [项目名称]cargo build 生成的目录结构如下:
.|-- Cargo.lock|-- Cargo.toml|-- src| `-- main.rs`-- target |-- CACHEDIR.TAG `-- debug |-- build |-- deps | |-- stark-2c1445affc8ccd97 | `-- stark-2c1445affc8ccd97.d |-- examples |-- incremental |-- stark `-- stark.d数据类型概述
类型是对二进制数据的一种约束行为。类型比起二进制数据,有许多优势:
减少开发者心智负担安全、容易优化常见的类型分类:
静态类型:在编译器对类型进行检查动态类型:在运行期对类型进行检查强类型:不允许隐式类型转换弱类型:允许隐式类型转换Rust是强类型语言。
Rust基本数据类型
1.Rust的变量
创建变量使用let关键字变量默认是不可变的,关键字前面加mut转换为可变变量常量使用const关键字定义隐藏属性2.基础数据类型
Rust是一门静态编程语言,所有变量的类型必须在编译期就被明确规定。
整数:Rust有12种不同类型的整数
对于未明确标明的类型的整数,Rust默认采用i32isize和usize根据系统不同而有不同的长度长度 | 有符号 | 无符号 |
|---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
128-bit | i128 | u128 |
arch | isize | usize |
fn main() { let number :i8 = 32; println!("{}",number);}浮点数型: Rust 与其它语言一样支持 32 位浮点数(f32)和 64 位浮点数(f64)。默认情况下,64.0 将表示 64 位浮点数,因为现代计算机处理器对两种浮点数计算的速度几乎相同,但 64 位浮点数精度更高。
fn main() { let x = 2.0; // f64 let y: f32 = 3.0; // f32}布尔值:布尔型用 bool 表示,值只能为 true 或 false。大小为一个字节。
fn main() { let t = true; let f: bool = false;}字符型:字符型用 char 表示。Rust的 char 类型大小为 4 个字节,代表 Unicode标量值,这意味着它可以支持中文,日文和韩文字符等非英文字符甚至表情符号和零宽度空格在 Rust 中都是有效的 char 值。
注意: Rust 中字符串和字符都必须使用 UTF-8 编码,否则编译器会报错。
复合类型
元组
元组用一对 ( ) 包括的一组数据,可以包含不同种类的数据:
fn main() { let a: i32= 10; let b = "A"; //创建一个元组 let mytuple:(i32,char) = (a,b); // 从元组中读取一个值 println!("{},{}",mytuple.0,mytuple.1); //解封装 let(c , d) = mytuple; println!(" {} , {} ",c , d);}数组
数组用一对 包括的同类型数据。Rust语法规定,每个数组的类型必须相同。Rust的数组中不同于其他一些语言中的数组,具有固定长度。
数组下标以0开始,同时Rust存在越界检查。
fn main() { //初始化数组 let myarray: [u32;5] = [1,2,3,4,5]; println!("myarray[1] = {}",myarray[1]); //数组越界 //let index = "5".parse::().unwrap(); //println!("myarray[5]={}",myarray[index]); let mut mybuffer: [u32;32 * 1024] = [10;32*1024]; println!("mybuffer[1024] = {}", mybuffer[1024]); //修改数组的值 mybuffer[1024] = 13; println!("mybuffer[1024] = {}", mybuffer[1024]);} 切片
切片(Slice)是对数据值的部分引用。切片这个名字往往出现在生物课上,我们做样本玻片的时候要从生物体上获取切片,以供在显微镜上观察。
fn main() { //切片可以切数组 let myarray: [u32;5] = [1,2,3,4,5]; let slice = &myarray[0..3]; println!("slice[0] = {}, slice.length = {} ",slice[0],slice.len()); //切片还可以切字符串 let s = String::from("broadcast"); let part1 = &s[0..5]; let part2 = &s[5..9]; println!("{}={}+{}", s, part1, part2);}Slice没有自己去存储数据,截取的都是引用数据。
结构体
结构体是多种不同数据类型的组合。它与元组类似,但区别在于我们可以为每个成员命名,可以使用struct关键字三种类型的结构。
元组结构经典的C结构无字段的单元结构结构体使用驼峰命名。
//元组结构struct Pair(i32,f32);//经典的C结构struct Peison { name:String, age:u8}fn main() { let pair = Pair(10,4.2); let person = Peison{ name: String::from("stark"), age:32 }; println!("pair.0 = {}",pair.0); println!("person.name = {}, person.age = {}",person.name,person.age);}引用派生属性,打印结构体。
#[derive(Debug)]struct Peison { name:String, age:u8}fn main() { let person = Peison { name: String::from("stark"), age:32 }; println!("{:?}",person);}枚举
枚举类在 Rust 中并不像其他编程语言中的概念那样简单,但依然可以十分简单的使用:
#[derive(Debug)]enum IPAddr { IPv4(u8,u8,u8,u8), IPv6(u8,u8,u8,u8,u8,u8,u8,u8,u8,u8,u8,u8),}fn main() { let localhost :IPAddr = IPAddr::IPv4(127,0,0,1); match localhost { IPAddr::IPv4(a,b,c,d) => { println!("{},{},{},{}",a,b,c,d); } _ => {} }}Rust - 流程控制、函数
if else
Rust的if的布尔条件不用括号括起来。if所有分支返回的类型必须相同。
fn main() { let number = 3; if number < 5 { println!("条件为 true"); } else { println!("条件为 false"); }}loop、while
Rust提供了loop一个关键字来表示无限循环。while是根据条件进行循环。
fn main() { let s = ["R", "U", "N", "O", "O", "B"]; let mut i = 0; loop { let ch = s[i]; if ch == "O" { break; } println!("\"{}\"", ch); i += 1; }}for range
Rust的 for in 语法可以用来遍历一个迭代器,有多种方法可以创建一个迭代器,最简单也是最常见的方式:
a..b:这里将创建一个a,但不包含b的,步长为1的迭代器a..=b:这里将创建一个a,且包含b的,步长为1的迭代器fn main() { for i in 0..5 { println!("i value is {}",i); } println!("-------------"); for i in 0..=5 { println!("i value is {}",i); }}for in 语法第二个重要的使用场景是遍历数组,但这首先将数组转化为一个迭代器,可以通过.iter()或者.iter_mut实现,区别是在于后者是可变的。
fn main() { let mut myarray = [1,2,3]; for i in myarray.iter(){ println!("i value is {} ",i); } for i in myarray.iter_mut() { *i *= 2; } for i in myarray.iter(){ println!("i value is {} ",i); }}遍历关联数组:
fn main() { let myarray = ["a","b","c"]; for i in myarray.iter(){ println!("i value is {} ",i); }}match / if_let / while_let
在Rust 中 没有 switch 语句,matcher 就是 switch 的一个变形,但比其他语言中的 switch 更强大!
let x = 5;match x { 1 => println!("one"), 2 => println!("two"), 3 => println!("three"), 4 => println!("four"), 5 => println!("five"), _ => println!("something else"),}函数与方法
函数
函数定义以fn为关键字,它的参数是带类型注释的,就像变量一样,如果函数返回值,则必须在箭头->之后指定返回类型。
fn sum_number(n:u64) -> u64 { if n < 2 { n }else{ n+1 }}fn main() { println!("sumNumber is {}",sum_number(10))}函数与闭包
Rust的闭包是一种匿名函数,它可以从它的上下文中捕获变量的值,闭包使用 ||-> 语法定义,闭包可以保存在变量中。
fn main() { let time3 = |n:u32| -> u32 { n * 3 }; println!("time3 is {}",time3(10));}move关键字可以从闭包环境中捕获值,它最常用的场景是将主线程中的一个变量传递到了子线程中。
use std::thread;fn main() { let hi = "hi,stark"; thread::spawn(move || { println!("stark value {}",hi); }).join();}高阶函数 / 发散函数
在数学和计算机科学里,高阶函数至少满足一个条件的函数:
接收一个或多个函数作为输入输出一个函数在数学中它们叫做算子或泛函,高阶函数是函数式编程中一个重要概念。
fn action(method:fn(u32,u32)->u32,a: u32,b: u32) -> u32 { method(a,b);}fn add(a:u32,b:u32) -> u32 { a + b }fn sub(a:u32,b:u32) -> u32 { a - b }fn main() { println!("{}",action(add,10,20))}发散函数
发散函数指的是永远不会被返回,它们的返回值标记!,这是一个空类型。
Rust - 使用模块、泛型、所有权
Rust项目的代码组织包含以下三个基本概念:
Package(包)Crate(箱)Module(模块)Package
Package 用于管理一个或多个Crate,创建一个Package的方式是使用cargo new stark命令:
[root@b0b5a9371ce4 stark]# tree.├── Cargo.toml└── src └── main.rs1 directory, 2 filesCreate
Create是Rust最小单元,既Rust是编译器是以Create为最小单元进行编译的。Create在一个范围内将相关的功能组合在一起,并最终通过编译器生成一个库文件或者是二进制文件。
Module
Module允许我们将一个Create中的代码组织成独立的代码块,以便增强可读性和代码复用,同时Module还控制代码的可见性,将代码分为公开和私有两种属性,定义一个模块的关键字是mod
Module的可见性
Rust中的模块内部的代码、结构体、函数默认是私有的,但是可以通过pub关键字来改变他们的可见性,通过选择性的对外可见性来隐藏模块内部的实现细节。
比较常见的三种pub写法:
pub 成员对模块可见pub(self) 成员对模块内的子模块可见pub(crate) 成员对整个crate可见mod mod1 { pub const MESSAGE :&str = "Hello,world";}fn main() { println!("{}",mod1::MESSAGE)}Module的引入
在文件开头使用mod 文件路径;,第二种可以映射到一个文件夹,但文件夹中要存在mod.rs,该文件夹可作为一个模块。
结构体的可见性
结构体的字段和方法默认是私有的,通过加上pub修饰语可使得结构体中的字段和方法可以在定义结构体外访问。要注意,与结构体同一个模块和代码的访问结构体中的字段和方法并不要求该字段是可见的。
use 绑定模块成员
使用use绑定类库,as可以指定别名。
使用super与self简化模块路径
除了使用完整路径访问模块内成员,还可以使用super与self关键字相对路径对模块进行访问。
super :上层模块self : 当前模块泛型
Rust中未指定参数类型的概念叫泛型。
函数参数的泛型
pub fn sum_number>(a:T,b:T) -> T { return a+b;} 结构体中的泛型
struct Point { x:T, y:T}struct Line { x: Point, y: Point}fn main() { println!("{}",cc::MESSAGE); println!("{}",cc::sum_number(10,20)); let pointx = Point{x:0,y:0}; let pointy = Point{x:10,y:10}; let line = Line {x:pointx, y:pointy}; println!("{},{},{}",line.x.x,line.x.y,line.y.x);} Rust内存管理
所有权是Rust这门语言的核心概念,Rust最以为豪的内存安全就建立在所有权之上。
Rust采用了一种中间的方案RALL,它兼具GC的易用性和安全性,同时又有极高的性能。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5MlOioAW-1649511656829)(https://note.youdao.com/yws/res/17856/WEBRESOURCE1759d05270a5a0ada71aa6cc869b2c73)
rust所有权
Rust中每个值都绑定有一个变量,称为该值的所有者。每个值只有一个所有者,而且每个值都有它的作用域。一但当这个值离开作用域,这个值占用的内存将被回收。fn main() { let s2:String; { let s1 = String::from("Hello,world"); s2 = s1; //println!("s1 value {}",s1); //value borrowed here after move } println!("s2 value {}",s2);}借用
在有些时候,我们希望使用一个值而不拥有这个值,这种需求在函数调用的时候特别常见。
fn echo(s:String){ println!("{}",s);}fn main() { let s = String::from("hello.world"); echo(s); println!("{}",s);}Rust一个变量只有一个所有权。
fn echo(s:&String){ println!("{}",s);}fn main() { let s = String::from("hello.world"); echo(&s); println!("{}",s);}不可变引用与可变引用
默认情况下,引用是不可变的,如果希望修改引用的值,需要使用&mut。
fn change(s: &mut String){ s.push_str("chenged!")}fn main() { // 要借用的变量s也需要是可变的变量 let mut s = String::from("hello.world"); change(&mut s); println!("{}",s);}同一时间内,至多有一个可变引用。
fn main() { let mut s = String::from("hello.world"); let s1_ref = &mut s; let s2_ref = &mut s; println!("{}",s1_ref); println!("{}",s2_ref);}生命周期注解
生命周期注解不会改变之前生命周期的长短,它还是原来的生命周期,注解是给编译器看的,拥有相同的生命周期注解,生命周期都是一样的。
fn bigger (str1:&str,str2:&str) -> &str { if str1 > str2 { str1 }else{ str2 }}fn main() { println!("{}",bigger("a","b"));}结构体当中的生命周期注释
#[derive(Debug)]struct Person { name: String}fn main() { let p = Person{ name:String::from("zhangyu") }; println!("{:?}",p );} -
2022-02-07 14:57:45
奇迹!绝杀!女足亚洲杯逆转夺冠!<
刚刚,中国女足上演逆转绝杀奇迹!她们在亚洲杯决赛中3:2力克韩国队,时隔16年再夺亚洲杯冠军!
-
2022-02-07 14:57:45
中国政府与阿根廷共和国政府签署共建“一带一路”谅解备忘录<
新华社北京2月6日电(记者安蓓)国家发展改革委6日称,国家发展改革委主任何立峰与阿根廷外交、国际贸易和宗教事
-
2022-02-07 14:57:43
中华人民共和国和阿根廷共和国关于深化中阿全面战略伙伴关系的联合声明(全文)<
新华社北京2月6日电中华人民共和国和阿根廷共和国关于深化中阿全面战略伙伴关系的联合声明一、应中方邀请,阿根廷
-
2022-02-07 14:57:40
春节假期国内旅游出游2.51亿人次<
春节遇冬奥,旅游年味浓。根据文化和旅游部数据中心测算,2022年春节假期7天,全国国内旅游出游2 51亿人次,同比
-
2022-02-07 14:57:40
中吉签署关于经典著作互译出版的备忘录 开启两国人文交流互鉴新阶段<
新华社北京2月6日电(记者史竞男)国家主席习近平6日会见来华出席北京2022年冬奥会开幕式的吉尔吉斯斯坦总统扎帕
-
2023-03-01 14:16:23
Rust - 安装环境、基本类型、流程控制、函数、模块、泛型、所有权
学习Rust语言是公司同事最先开始提议的,准备用接下来的项目试试水,Rust是一个强类型编译型语言,比较偏向底层,所以开启了Rust的探索之旅。
-
2023-03-01 12:05:42
天天热讯:仁恒去年纯利跌42.3%至见15.33亿元
观点网讯:3月1日,仁恒公布截至去年12月底的全年业绩。公司去年股东应占利润录得15 33亿元,同比下跌42 3%;每股盈利79 34分。收入同比跌17 6%至
-
2023-03-01 11:19:31
焦点讯息:小米手机忘记密码怎么恢复出厂设置?
1、嗨!打开电脑小米网官网。2、在登陆处直接点击密码找回2、输入你的手机号。3、获取验证码3、修改密码后返回登陆小
-
2023-03-01 09:53:19
杭师大回应"教师被投诉骚扰女生等" 环球聚焦
2月17日,有网友在浙江省政府网站“浙江省民呼我为统一平台”举报“杭州师范大学教授石然性骚扰、学术欺骗和滥用职权等行为”。该网友称,...
-
2023-03-01 08:00:02
当前焦点!qq名字英语带翻译_qq英语名字
1、酸奶(酸奶)2、樱桃3、浅水(浅滩)4、刺痛5、晦涩(晦涩)6、Lcbkmm参与7、偏爱(偏爱)8、歇斯底里症9、激怒(激怒)10、甜美的仙女(甜美的女孩)
-
2023-03-01 05:57:51
环球快资讯丨觅的意思_觅食的意思
1、觅食的觅在觅食一词中的意思——寻找。本文到此分享完毕,希望对大家有所帮助。
-
2023-03-01 03:50:56
【独家】消防安全手抄报内容文字_消防安全手抄报内容
1、火灾逃生自救十法一要了解和熟悉环境。2、当你走进商场、宾馆、酒楼、歌舞厅等公共场所时,要留心太平门、安全出口、灭火
-
2023-02-28 23:52:13
水梅花春天几天浇一次水 水梅花的浇水频率 热消息
1、水梅花在春季生长期每隔2-3天浇水一次,这样就可以满足它的生长需求,当空气干燥时候,可以向其周围或叶面喷施水,保持一定的环境湿润度。2
-
2023-02-28 18:52:49
野生干海参如何保存 野生干海参怎么保存|环球播报
1、干海参保存在干燥通风的地方就可以了,因为海参的肉质已经干枯,外表还裹这一层盐,隔绝了空气,不会坏。 2、为了怕影响其质量和口感,
-
2023-02-28 16:20:15
环球简讯:吉贝尔(688566)龙虎榜数据(02-28)
沪深交易所2023年02月28日公布的交易公开信息显示,吉贝尔因成为日涨幅达到15%的前5只证券而登上龙虎榜。
-
2023-02-28 15:13:46
pilaster-世界热议
1、pilaster,英语单词,主要用作名词,作名词时译为“壁柱,半露方柱”。2、。文章到此就分享结束,希望对大家有
-
2023-02-28 14:55:27
威海市商业银行 创新专班模式 助推普惠金融
党的二十大报告指出,要坚持把发展经济的着力点放在实体经济上。发展普惠金融既是服务实体经济的重要抓手,也是深化金融供给侧改革的关键环节
-
2023-02-28 12:10:53
北欧四国是哪四个省_北欧四国是哪四国
1、北欧四国是芬兰。2、丹麦。3、瑞典。4、挪威芬兰的首都是赫尔辛基瑞典的首都是斯德哥尔摩丹麦的首都是哥本哈
-
2023-02-28 10:46:23
threed32.ocx丢失_threed32 ocx_全球视点
1、Threed32 ocx控件常规安装方法(仅供参考):一、如果在运行某软件或编译程序时提示缺少、找不到Threed3
-
2023-02-28 09:40:06
观热点:TCT自动细胞制片机
1、TCT自动细胞制片机是宫颈癌细胞学检查技术。文章到此就分享结束,希望对大家有所帮助。
-
2023-02-28 09:04:30
今日怎样隐藏好友的微信号_怎么对好友隐藏微信号 世界最资讯
1、如果你设置了微信号,你就藏不住了。2、必须重新申请一个新的微信号。3、不用设置微信号,直接用你的手机号或者QQ号做微
-
2023-02-28 06:10:18
天天快看:就业讲座|春招节奏分析与求职策略应对,2月28日19:00,“京彩助梦 成功就业”线上公益讲座
就业讲座“京彩助梦成功就业”线上公益讲座2月第二讲即将开讲!讲座时间:2月28日晚上19:00-20:00讲座主题:春招节奏分析与求职策略应对讲座师
-
2023-02-28 04:11:19
信息:好看森系图片女生动漫_森系动漫女生图片
1、原图这些可以吗那个的原图没有,不过有这些,。2、,我选了一些,。3、望采纳!!!!!!!!!!!!!!!!!!!!!
-
2023-02-28 00:58:01
大姨妈来了吃什么好?_大姨妈来了吃什么好些|每日聚焦
1、部分女性在经期会出现烦躁、乏力、失眠、厌食等症状,这些都是正常的,与体内激素分泌有关。2、可以通过合理选择食物来调理
-
2023-02-27 21:55:42
泗洪县教育局官网教师晋级办法_泗洪县教育局官网
1、综合管理教育系统的安全和维稳工作。2、负责接待和处理群众来信来访工作、矛盾纠纷的排查调处工作;负责教育系统社会治安综
-
2023-02-27 19:06:41
全球今日报丨港珠澳大桥珠海口岸微门户上怎么寻找自己的车?
对于驾车前往口岸的司机,在“港珠澳大桥珠海口岸微门户”上,“寻找爱车”功能可以充分解决司机在停车场迷路的烦恼!寻找爱车第一步:点击...
-
2023-02-27 18:58:27
word如何删除页面空白页_word如何删除页面
1、删除Word文件中指定页的方法:第一步:在编辑菜单下选中“定位”。2、第二步,在打开的对话框,定位标签栏下进行相应设
-
2023-02-27 16:48:55
怎样祛痘痘疤痕小妙招_怎样去痘痘
1、祛痘的话给你介绍几种祛痘小窍门,都很有效:祛痘小窍门一:白醋+食盐将半汤匙白醋加入到一汤匙食盐中,然后再加点冷开水,
-
2023-02-27 15:15:06
观焦点:渝论|落实8小时工作制,不能只是一句空话
2月25日,全国政协委员蒋胜男在接受采访时表示,在“后疫情时代”更应加强对劳动者休息权的保护,对企事业单位8小时工作制执
-
2023-02-27 13:29:29
虹吸马桶下水慢没有吸力怎么处理_虹吸马桶下水慢没有吸力 每日观点
1、有几个原因一.水量水位不够,配件安装不当,调配不好。2、二.本身下水管道有堵塞,或其它问题三.马桶虹吸管道漏气,马桶
-
2023-02-27 12:52:24
插混市场又添新兵 长安智电iDD双车上市
近日,首批搭载长安智电iDD的UNI-V智电iDD和UNI-K智电iDD也正式上市。其中,UNI-V智电iDD共推出2款车型,售价区间为14 49万-15 99万元,并推出
-
2023-02-27 11:10:50
河北银行电话认证_河北银行电话
1、河北银行客服电话:1 客服热线0311-963682 客服热线400-612-9999拓展资料:河北银行成立于199
-
2023-02-27 09:52:13
评剧《杜十娘》在全国地方戏演出中心演出
2月26日,评剧演员在北京全国地方戏演出中心演出剧目《杜十娘》。当日,在由石家庄市文旅局、石家庄市艺术研究院主办的“2023精品剧目交流演出
-
2023-02-27 08:04:43
巨鹿之战-世界短讯
1、巨鹿之战,是秦末大起义中,项羽率领数万楚军(后期各诸侯义军也参战)。2、同秦名将章邯、王离所率四十万秦军主力在巨鹿
-
2023-02-27 07:10:38
环球看热讯:吃火锅的菜品有哪些_吃火锅的菜品种类
欢迎观看本篇文章,小升来为大家解答以上问题。吃火锅的菜品有哪些,吃火锅的菜品种类很多人还不知道,现在让我们一起来看看吧!