Rust通用编程概念(3)
Rust通用编程概念
- 1.变量和可变性
- 1.执行`cargo run`
- 2.变量
- 3.变量的可变性
- 4.常量
- 5.遮蔽
- 5.1遮蔽与mut区别
- 1.遮蔽
- 2.mut
- 2.数据类型
- 1.标量类型
- 1.1整数类型
- 1.2浮点数类型
- 1.3数字运算
- 1.4布尔类型
- 1.5字符类型
- 2.复合类型
- 2.1元组类型
- 2.2数组类型
- 1.访问数组
- 2.无效的数组元素访问
- 3.函数
- 3.1定义函数
- 3.2参数
- 1.参数使用的注意事项
- 3.3语句和表达式
- 3.4带有返回值的函数
- 4注释
- 4.1单行注释
- 4.2多行注释
- 4.3文档注释
- 5.控制流
- 5.1if表达式
- 5.2使用else if处理多重条件
- 5.3在let语句中使用if
- 5.4使用循环重复执行
- 1.使用loop重复执行代码
- 1.1从循环返回
- 2.while条件循环
- 3.使用for遍历集合
1.变量和可变性
fn main() {let x = 10;println!("The value of x is:{}", x);x = 12;println!("The value of x is:{}", x)
}
1.执行cargo run
- 下图就是执行之后的报错信息
2.变量
- rust定义的普通变量不能修改
let [变量名] = [变量值]
3.变量的可变性
- rust虽然普通定义的变量不可修改,可以添加关键字
mut
,让变量具有可变性
let mut [变量名] = [变量值]
fn main(){let mut x = 10;println!("The value of x is:{}",x);x = 12;println!("The value of x is:{}",x);
}
cargo run
The value of x is: 5
The value of x is: 6
4.常量
- 常量是绑定一个常量名且不允许更改的值
- 常量不允许使用
mut
- 常量使用
const
不是let
关键词来声明,并且值的类型必须注明 - 常量可以在任意作用域内声明
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
5.遮蔽
fn main(){let x = 8;let x = x + 1;{let x = x * 2;println!("The value of x in the inner scope is:{}",x);// 18}println!("The value of x is: {}",x);// 9
}
- 首先将数值8绑定到x
- 通过重复使用let x = 来遮蔽之前的x,并取原来的值+1
- 作用域内,第三个let语句同样遮蔽前面的x,并且取之前值 * 2
- 作用域结束,内部遮蔽结束并且x恢复为9
5.1遮蔽与mut区别
1.遮蔽
- 通过let关键字,再一次有效的创建一个新的变量
let spaces = " ";// 字符串
let spaces = spaces.len();// 数字类型
2.mut
- mut关键词主要是对变量的修改
let spaces = " ";// 字符串
// spaces = spaces.len();// error,数字类型,赋值类型发生变化
2.数据类型
- Rust的每个值都有确切的数据类型,以下将主要展开两种数据类型:标量类型和复合类型
- Rust是一种静态类型的语言
// cosider giving `guess` a type
// let guess = "90".parse().expect("Not a number!");
let guess: u32 = "90".parse().expect("Not a number!");
1.标量类型
1.1整数类型
长度 | 有符号类型 | 无符号类型 |
---|---|---|
8位 | i8 | u8 |
16位 | i16 | u16 |
32位 | i32 | u32 |
64位 | i64 | u64 |
128位 | i128 | u128 |
arch | isize | usize |
- 有符号类型的数字范围是-2^(n-1) ~ 2^(n-1)-1
- 无符号类型的数字范围是0~2^(n)-1
- isize和usize类型取决于程序运行的计算机体系结构,64位架构系统则位64位,32位结构系统则为32位
- isize和usize的主要场景是用作某些集合的索引
1.2浮点数类型
- 浮点数是带有小数点的数字,Rust中的浮点类型也有两种基本类型
- Rust的浮点型是f32和f64,默认浮点类型是f64
fn main(){
let x = 2.3; // f64
let y: f32 = 3.2; //f32}
1.3数字运算
- rust的所有数字类型都支持数学运算:加、减、乘、除和取模运算
- 整数除法会向下取整
//additionlet sum = 5 + 10;println!("{}", sum);// 15//subtractionlet difference = 96.6 - 94.7;println!("{}", difference);// 1.8999...//multiplicationlet product = 4 * 20;println!("{}", product);// 80//divisionlet quotient = 63.3 / 23.3;let floored = 2 / 3;println!("{}", quotient);// 2.71673...println!("{}", floored);// 0//remainderlet remainder = 43 % 5;println!("{}", remainder);// 3
1.4布尔类型
- Rust中的布尔类型也有两个可能的值:true和false
- 布尔值的大小为1个字节
- Rust中的布尔值使用bool声明
fn main(){let t = true;let f: bool = false
}
1.5字符类型
- Rust的char(字符)类型是该语言基本的字母类型
- Rust的字符类型大小为4个字节,表示一个Unicode标量值
fn main(){let c = 'c';let b = 'b';let heart_eyed_cat = '🐱';}
2.复合类型
- 复合类型可以将多个值组成一个类型,Rust有两种基本的复合类型:元组 和 数组
2.1元组类型
- 元组是将多种类型的多个值组合到一个复合类型中的基本方式
- 元组的长度是固定的,声明后,它就无法增产或缩小
fn main(){let tup: (i32,f64,u8) = (500,23.3,5);
}
- 变量tup绑定到整个元组,因为元素被认作是单个复合元素
- 可以使用模式匹配来解构元组的一个值
fn main(){let tup = (500,6.2,3);let (x,y,z) = tup;println!("The value of y is:{}",y);// 6.4}
- 通过模式匹配进行结构外,还可以通过 . 连上访问值得索引来直接访问元组元素
- 元组中的第一个索引从0开始
fn main(){let x: (i32,f64,u8) = (500,6.3,23);let five_hundred = x.0;let six_point_three = x.1;let twenty_three = x.2;println!("{}",twenty_three);}
2.2数组类型
- 将多个值组合在一起的另一种方式就是使用数组;与元组不同,数组的每个元素必须具有相同的类型;与其他语言不同数组不同的是,Rust中的数组具有固定长度.
- 应用场景
- 确保始终具有固定数量的元素,数组特别有用
- Vector,在Rust里面,意为"动态数组,可变数组"
- Vector类型类似于标准库中提供的集合类型
let arr = [12,13,89,56,14];
- 另一种数组初始化方式
// 变量名为arr的数组包含5个元素,这些元素的初始值都是3
let arr = [3;5]
1.访问数组
- 数组是可以在栈上分配已知固定大小的单个内存块
- 可以使用索引访问数组的元素
let arr = [12, 13, 89, 56, 14];let first = arr[0];let second = arr[1];println!("{}", first); // 12println!("{}", second); // 13
}
2.无效的数组元素访问
- 访问超出数组末尾的数组元素
use std::io;
fn main() {let arr = [12, 16, 45, 13, 19];println!("please enter an array index.");let mut index = String::new();io::stdin().read_line(&mut index).expect("Failed to read line");let index: usize = index.trim().parse().expect("Index entered was not a number");let element = arr[index];println!("The value of the element at index {} is: {}",index, element);
}
- 该案例在索引操作使用无效值时导致运行时错误,程序退出并提示错误信息,未执行后面的println!语句
- rust将检查你指定的索引是否小于或等于数组长度;索引大于或等于数组长度,rust会出现panic
3.函数
- main函数,它是很多程序的入口点
- Rust代码中的函数和变量名使用下划线命名法规范风格
- 在下划线命名法中,所有字母都是小写并使用下划线分隔单词
fn main(){println!("main funcation");another_funcation();
}
fn another_function(){println!("another function")
}
3.1定义函数
- Rust中函数定义以
fn
开头,后跟着函数名和一对括号;大括号告诉编译器函数体在哪开始和结束
3.2参数
- 函数可以被定义拥有参数,参数是特殊变量,是函数签名的一分部
- 当函数拥有参数(形参)时,这些参数提供具体的值(实参)
- 日常交流中,人们倾向于不区分使用
parameter
和argument
来表示函数定义中的变量或调用函数时传入的具体值
fn main(){number_function(10);
}
fn number_function(x: i32){println!("The value of x is:{}",x);//10
}
1.参数使用的注意事项
- 函数签名中,必须声明每个参数的类型
- 要求在函数定义中提供类型,意味着编译器几乎从不需要你在代码其他位置注明类型来指出你的意图
- 一个函数有多个参数时,需要用
逗号隔开
fn main(){print_labeled_measurement(5,'h');
}fn print_labeled_measurement(value: u32,unit_label: char){println!("The measurement is:{}{}",value,unit_label);// 5h
}
3.3语句和表达式
- 函数体由一系列语句组成,也可以选择表达式结尾
- 语句是执行一些操作但不返回值的指令
- 表达式计算并产生一个值
//语句和表达式let y = 6;println!("{}", y);// 语句不会返回值// let x1 = (let y = 6);let y1 = {let x1 = 5;//行的末尾没有分号,表达式末尾加分号,那么它就转换为语句,而语句不会返回值x1 + 1};println!("The value of y1 is:{}", y1); // 6
3.4带有返回值的函数
- 函数可以向调用它的代码返回值,但要在箭头(->)后声明它的类型
- 在Rust中,函数的返回值等同于函数体最后一个表达式的值
- 使用return关键字和指定值,可以从函数中提前返回;大部分函数隐式返回最后一个表达式
fn five() -> u32{5
}
fn main(){let x = five();println!("The value of x is: {}“,x);
}
- 谨慎使用分号
fn five_plus(x: u32) -> u32{//如果在X+1后面加分号,表示语句,没有返回值,将报错// x + 1;x + 1
}
fn main(){let y = five_pluse(5);println!("{}",y); //6
}
4注释
4.1单行注释
- Rust中,惯用的注释形式以两个斜杠开头,直到该行尾结束
- 对于超出单行的注释,需要在每行的行首加上
//
fn main(){//I'm feeling lucky todaylet lucky_number = 7;// I’m feeling lucky today
}
4.2多行注释
- 使用斜杠星号开始和星号斜杠结束,可以跨越多行的注释
/*
这是一个做计算的方法注意传值要求
*/
fn plus_number(x: u32,y: i32) -> u32{x + y
}
4.3文档注释
- Rust允许你使用特殊的文档注释来为函数、结构体、枚举等代码元素添加文档注释
- 文档注释以
///
开始,通常紧跟在你要注释的代码元素之前
/// 这是一个文档注释
fn my_function(){}
5.控制流
- 根据条件是否为真来决定是否执行某些代码或根据条件是否为真来重复运行一段代码
- Rust代码中最常见的用来控制执行流的结构是if表达式和循环
5.1if表达式
- if 表达式允许根据条件执行不同的代码分支
fn main(){let number = 3;if number < 5 {println!("condition was true");}else{println!("condition was false");}
}
- 需要注意的事代码中的条件必须是bool值
5.2使用else if处理多重条件
- 可将if 和 else组成的 else if 表达式来实现多重条件
fn main(){let number = 6;if number % 4 == 0 {println!("number is divisible by 4");}else if number % 3 == 0 {println!("number is divisible by 3");}else if number % 2 == 0 {println!("number is divisible by 2");}else{println!("number is not divisible by 4,3,or 2");}}
- 注意事项
- 使用过多的else if 表达式回事代码显得杂乱无章,如果超过一个else if 表达式,最好重构代码
- 使用rust强大的分支结构,match
5.3在let语句中使用if
- if是一个表达式,可以在let语句的右侧使用它来将结果赋值给一个变量
fn mian(){let condition = true;let number = if condition { 5 } else {6};println!("The value of number is:{}",number);// 5
}
5.4使用循环重复执行
- Rust有三种循环:loop、while和for
1.使用loop重复执行代码
- loop关键字告诉rust一遍又一遍执行一段代码知道你明确要求停止
fn main(){//这是一个死循环,通过ctrl+c终止循环loop{println!("again!");}
}
- 存在嵌套循环,关键词break或continue可以和标签一起使用,有利于业务的实现
fn main(){let mut count = 0;'counting_up': loop{println!("count = {}",count);let mut remaining = 10;loop {println!("reamining = {}",remaining); if remaining == 9 {break;}if count == 2 {break 'counting_up';} remaining -= 1;}count += 1;}println!("End count = {}",count);
}
1.1从循环返回
- loop的一个用例是重试可能会失败的操作
- 有时可能会需要将操作的结果从循环中传递给其他的代码
- 可以用停止循环的
break
表达式添加你想要的返回值
fn main(){let mut counter = 0;let result = loop {counter += 1;if counter == 10 {break counter * 2;}};println!("The value is {}",result); // 20}
2.while条件循环
fn main(){let mut number = 3;while number != 0{println!("{}",number);number -= 1;}println!("LIFTOFF!!!");
}
3.使用for遍历集合
- while也可以实现遍历集合,但是容易出现下标越界问题,所以一般建议不使用
- 更加推荐for去实现业务逻辑
fn main() {let arr = [10,20,30,40,50];for element in arr {println!("the value is: {}",element);}
}
相关文章:

Rust通用编程概念(3)
Rust通用编程概念 1.变量和可变性1.执行cargo run2.变量3.变量的可变性4.常量5.遮蔽5.1遮蔽与mut区别1.遮蔽2.mut 2.数据类型1.标量类型1.1整数类型1.2浮点数类型1.3数字运算1.4布尔类型1.5字符类型 2.复合类型2.1元组类型2.2数组类型1.访问数组2.无效的数组元素访问 3.函数3.1…...

学Python的漫画漫步进阶 -- 第四步
学Python的漫画漫步进阶 -- 第四步 四、运算符4.1 算术运算符4.2 比较运算符4.3 逻辑运算符4.4 位运算符4.5 赋值运算符4.6 运算符的优先级4.7 练一练4.8 运算符的总结全部16步完成后 ,后续就是介绍项目实战,请大家给予点赞、关注! 四、运算符…...

【LeetCode-中等题】18. 四数之和
文章目录 题目方法一:双指针(定2动2) 题目 方法一:双指针(定2动2) 这题可以参考【LeetCode-中等题】15. 三数之和 区别在于,三数之和只需要用一个for循环定住一个数,然后设置两个前…...
每日一题 102二叉树的层序遍历
题目 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 示例 2:…...

牛客: BM4 合并两个排序的链表
牛客: BM4 合并两个排序的链表 文章目录 牛客: BM4 合并两个排序的链表题目描述题解思路题解代码 题目描述 题解思路 以链表一为主链表,遍历两条链表 若当前链表二的节点val小于当前链表一的下一个节点val,则将链表链表二的该节点连到链表一的节点的下一个,链表一的当前节点往…...

C语言基础知识点(六)二维数组指针和地址
#include <stdio.h>int main() {int a[2][3] {2, 4, 6,8, 10, 12};printf("a:%p, a1:%p\n", a, a 1); // 相差3*sizeof(int)12,二维数组名是一个指向每一行的指针,a:0061FF08, a1:0061FF14prin…...
nodejs格式化输入
需求 比如我现在要格式为Axxx-xxx(xxx是数字)的格式,但是输入有可能为A1-2这种情况,就需要补零,变成A001-002 代码实现 const regex /^A(\d)\-(\d)$/; // 正则匹配桩号合法格式const match input.match(regex);if…...

国家网络安全周 | 金融日,一起 get金融行业数据安全
2023国家网络安全宣传周 热度一直在持续! 9月15日是国家网络安全宣传金融日。 目前随着国际形势愈发严峻,金融机构基础设施的全面数字化升级,带来了全新的安全问题。数据安全不单是技术问题,更是已经成为一个关系社会稳定发展的…...

分布式事务解决方案之TCC
分布式事务解决方案之TCC 什么是TCC事务 TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认 Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个…...
Git 的基础命令 码云 gitee
就比如,我们的开发吧,我自己本地分支是dqh,远程分支也是new //我开始提交代码 //1,git add . //2,git commit -mXXX功能 //3,git pull origin new(你们现在这个版本的开发分支) //这里…...

探索工业4.0:数字孪生如何重塑工业生产流程?
在过去的几十年里,工业生产经历了从机械化、自动化到数字化的巨大转变。随着工业4.0的到来,我们正处于第四次工业革命的边缘,这次革命将由数字孪生技术引领。本文将深入探讨数字孪生在工业生产中的应用和潜力。 数字孪生(Digital …...

window server事件ID说明
重启:1074 6013:系统运行时间 6008:非正常关机或者意外关机 WindowsServer2012R2事件id6008什么意思? 在Windows Server 2012 R2中,事件ID 6008是一个系统事件,它通常表示系统的非正常关机或意外关机。当系…...

router-link 和 router-view的区别
router-link 实现路由之间的跳转 router-view(路由出口组件 -> 渲染路径匹配到的视图组件) 当你访问的地址与路由path相符时,会将指定的组件替换该router-view router-link router-link 点击实现路由跳转,to属性指向目标地址&…...
【Leetcode】139.单词拆分
一、题目 1、题目描述 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 示例1: 输入: s = “leetcode”, wordDict = [“leet”, “cod…...
PMP考试一定要报培训班吗?
随着近年来PMP证书在国内日渐吃香,越来越多人开始报考PMP考试,甚至不少企业还会通过各项奖励政策来鼓励内部项目骨干去考取PMP证书。 免费送备考资料。 很多初次参加PMP考试的人会有这种疑惑,那就是考PMP证书必须要参加培训班吗? 在我看来&…...
dart 学习 之 Getters and setters
前言 任何需要对属性进行更多控制而不是允许简单字段访问的时候,你都可以自定义 getter 和 setter。 正文 讲解 Getter(获取器)和Setter(设置器)是面向对象编程中用于控制对类属性访问的特殊方法。Getter用于获取属…...

使用融云 CallPlus SDK,一小时实现一款 1V1 视频应用
9 月 21 日,融云直播课 社交泛娱乐出海最短变现路径如何快速实现一款 1V1 视频应用? 欢迎点击小程序报名~ 1V1 音视频、远程服务类应用的实现利器——融云 CallPlus SDK 上线! 关注【融云全球互联网通信云】了解更多 作为新一代音视频通话场…...

Redis Part1
单体架构:一台Web服务器、一台数据库服务器。 1.了解NoSql 什么是Nosql? NoSQL,即Not-Only-SQL,意思就是我们干事情不能只用SQL,泛指非关系型的数据库!NoSQL定位:作为关系型数据库的补充&am…...

代理HTTP使用不当会出现哪些问题?如何正确使用代理服务?
代理HTTP是一种常见的网络代理方式,它为客户端和服务器之间提供中间层,转发上下游的请求和响应。正确使用代理HTTP可以提高采集效率、增加网络安全性、加速网络速度、保护用户隐私。但是,使用不当就难以达到预期的效果,在使用代理…...

利用芯片74hc165为单片机增加输入扩展端口proteus仿真arduino
我们前面的博文《输入端口少如何扩展?74hc148或74ls148级联在arduino中实现16转4的应用》介绍了148,148输入后可以立即输出到数码管,可以说它是自带编BCD编码器的。而今天这里我们主要介绍的74hc165是没有编码器,这里我们以proteus为仿真环境…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...