Rust通用编程概念
-
- 1.变量和可变性
-
- 1.执行`cargo run`
- 2.变量
- 3.变量的可变性
- 4.常量
- 5.遮蔽
-
- 2.数据类型
-
- 1.标量类型
-
- 1.1整数类型
- 1.2浮点数类型
- 1.3数字运算
- 1.4布尔类型
- 1.5字符类型
- 2.复合类型
-
- 3.函数
-
- 3.1定义函数
- 3.2参数
-
- 3.3语句和表达式
- 3.4带有返回值的函数
- 4注释
-
- 5.控制流
-
- 5.1if表达式
- 5.2使用else if处理多重条件
- 5.3在let语句中使用if
- 5.4使用循环重复执行
-
- 1.使用loop重复执行代码
-
- 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.变量
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);
}
println!("The value of x is: {}",x);
}
- 首先将数值8绑定到x
- 通过重复使用let x = 来遮蔽之前的x,并取原来的值+1
- 作用域内,第三个let语句同样遮蔽前面的x,并且取之前值 * 2
- 作用域结束,内部遮蔽结束并且x恢复为9
5.1遮蔽与mut区别
1.遮蔽
let spaces = " ";
let spaces = spaces.len();
2.mut
let spaces = " ";
2.数据类型
- Rust的每个值都有确切的数据类型,以下将主要展开两种数据类型:标量类型和复合类型
- Rust是一种静态类型的语言
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;
let y: f32 = 3.2;
}
1.3数字运算
- rust的所有数字类型都支持数学运算:加、减、乘、除和取模运算
- 整数除法会向下取整
let sum = 5 + 10;
println!("{}", sum);
let difference = 96.6 - 94.7;
println!("{}", difference);
let product = 4 * 20;
println!("{}", product);
let quotient = 63.3 / 23.3;
let floored = 2 / 3;
println!("{}", quotient);
println!("{}", floored);
let remainder = 43 % 5;
println!("{}", remainder);
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);
}
- 通过模式匹配进行结构外,还可以通过 . 连上访问值得索引来直接访问元组元素
- 元组中的第一个索引从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];
let arr = [3;5]
1.访问数组
- 数组是可以在栈上分配已知固定大小的单个内存块
- 可以使用索引访问数组的元素
let arr = [12, 13, 89, 56, 14];
let first = arr[0];
let second = arr[1];
println!("{}", first);
println!("{}", second);
}
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);
}
1.参数使用的注意事项
- 函数签名中,必须声明每个参数的类型
- 要求在函数定义中提供类型,意味着编译器几乎从不需要你在代码其他位置注明类型来指出你的意图
- 一个函数有多个参数时,需要用
逗号隔开
fn main(){
print_labeled_measurement(5,'h');
}
fn print_labeled_measurement(value: u32,unit_label: char){
println!("The measurement is:{}{}",value,unit_label);
}
3.3语句和表达式
- 函数体由一系列语句组成,也可以选择表达式结尾
- 语句是执行一些操作但不返回值的指令
- 表达式计算并产生一个值
let y = 6;
println!("{}", y);
let y1 = {
let x1 = 5;
x1 + 1
};
println!("The value of y1 is:{}", y1);
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
}
fn main(){
let y = five_pluse(5);
println!("{}",y);
}
4注释
4.1单行注释
- Rust中,惯用的注释形式以两个斜杠开头,直到该行尾结束
- 对于超出单行的注释,需要在每行的行首加上
//
fn main(){
let lucky_number = 7;
}
4.2多行注释
- 使用斜杠星号开始和星号斜杠结束,可以跨越多行的注释
fn plus_number(x: u32,y: i32) -> u32{
x + y
}
4.3文档注释
- Rust允许你使用特殊的文档注释来为函数、结构体、枚举等代码元素添加文档注释
- 文档注释以
///
开始,通常紧跟在你要注释的代码元素之前
fn my_function(){
}
5.控制流
- 根据条件是否为真来决定是否执行某些代码或根据条件是否为真来重复运行一段代码
- Rust代码中最常见的用来控制执行流的结构是if表达式和循环
5.1if表达式
fn main(){
let number = 3;
if number < 5 {
println!("condition was true");
}else{
println!("condition was false");
}
}
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.4使用循环重复执行
1.使用loop重复执行代码
- loop关键字告诉rust一遍又一遍执行一段代码知道你明确要求停止
fn main(){
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);
}
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);
}
}