个人如何建立免费网站,广告游戏,当地信息网站建设资质,怎么才能自己创一个平台文章目录 一、if流程控制与match模式匹配1.流程控制2. IF流程控制3.match 表达式 二、循环与break continue以及与迭代的区别1.Rust中的循环Loops2.break continue3.迭代4.循环与迭代的不同 三、函数基础与Copy值参数传递1.函数的基础知识2.Copy by value 四、函数值… 文章目录 一、if流程控制与match模式匹配1.流程控制2. IF流程控制3.match 表达式 二、循环与break continue以及与迭代的区别1.Rust中的循环Loops2.break continue3.迭代4.循环与迭代的不同 三、函数基础与Copy值参数传递1.函数的基础知识2.Copy by value 四、函数值参数的传递、不可变借用参数的传递、可变借用参数的传递1.函数值参数传递move2.不可变借用就是C的引用3.可变借用 五、函数返回值与所有权机制1.返回Copy与Non-Copy2.返回引用 六、高阶函数函数作为参数与返回值1.高阶函数与集合 参考 一、if流程控制与match模式匹配
1.流程控制
Execution Flow(流程)
1.代码执行从上倒下Iine-by-line2.而我们执行操作时控制流程可能会改变
主要的流程控制结构 1.顺序结构(Sequential Structure):程序按照代码的顺序一步一步执行没有跳过或循环。
2.选择结构(Selection Structure): -根据条件选择不同的路径执行。常见的选择结构有
if语句根据条件执行不同的代码块。switchi语句在某些编程语言中根据不同的条件值执行不同的代码块。
3.循环结构(Iteration Structure):重复执行一段代码直到满足某个条件为止。常见的循环结构有
for循环按照指定的次数重复执行一段代码。while循环在条件为真的情况下重复执行一段代码。do-while循环类似于while循环但是保证至少执行一次循环体。
4.跳转结构控制程序的执行流程跳转到指定的位置。常见的跳转结构有
break语句终止循环或switch语句的执行。continue语句跳过当前循环中的剩余代码进入下一次迭代。goto语句在某些编程语言中直接跳转到指定的标签处。
2. IF流程控制
代码一行行执行 执行流程被If(else)改变 可以嵌套使用但容易引起可读性问题 3.match 表达式
match用于模式匹配允许更复杂的条件和分支。
可以处理多个模式提高代码的表达力。
·match是表达式可以返回值。
match value{pattern1 /code block executed if value matches pattern1,pattern2 if condition /code block executed if value matches pattern2 and condition is true,_/code block executed for any other case,
}IF流程控制与match表达式对比 复杂性if适用于简单的条件判断而match更适用于复杂的模式匹配。 表达力match更灵活可以处理多个条件和模式使代码更清晰。 返回值两者都是表达式可以返回值但match通常用于更复杂的场景。
fn main() {let age 50;if age 50 {println!(You are young);} else {println!(You are old);}// if 的表达能力很弱let scores 70;if scores 90 {println!(Good!!!);} else if scores 60 {println!(You are OK!);} else {println!(Bad!!!);}// 类似C 三元表达式let msg if age 50 { old } else { young };println!(You are {msg});// matchlet num 90;match num {80 println!(80),90 println!(90),_ println!(Some else),}match num {25..50 println!(25 ... 50),51..100 println!(51 ... 100),_ println!(Some else),}match num {25 | 50 | 75 print!(25 or 50 or 75),100 | 200 println!(100 or 200),_ println!(Some else),}// match 里面使用ifmatch num {x if x 60 println!(bad),x if x 60 println!(luck),_ println!(Some else),}let num 60;let res match num {x if x 60 bad.to_owned(),x if x 60 luck.to_owned(),_ Some else.to_owned(),};println!(res value : {res});
}
编译及运行
cargo runCompiling ch11_if_match v0.1.0 (/home/wangji/installer/rust/project/ch11_if_match)Finished dev profile [unoptimized debuginfo] target(s) in 7.55sRunning target/debug/ch11_if_match
You are old
You are OK!
You are yong二、循环与break continue以及与迭代的区别
1.Rust中的循环Loops
Rust提供了几种循环结构其中最常见的是Ioop、while和for。
1.Ioop循环
loop{
///无限循环的代码块
}Ioop创建一个无限循环可以通过break语句来中断循环。
2.while循环
while condition{
//条件为真时执行的代码块
}while循环在每次迭代之前检查一个条件只有在条件为真时才执行循环体。
3.for循环
for item in iterable
{//遍历可迭代对象执行的代码块
}for循环用于迭代集合或范围执行代码块来处理每个元素。
2.break continue
·break关键字用于立即终止循环并跳出循环体
可以用于跳出指定标签循环
·continue关键字用于立即跳过当前循环中剩余的代码直接进入下一次循环
3.迭代
Rust的迭代主要通过迭代器(iterators)来实现。迭代器是一个抽象它提供了一种访问集合元素的统一方式。
从实现上讲在Rust中迭代器是一种实现了Iterator trait的类型
简化源码
pub trait lterator{type Item;fn next (mut self)-OptionSelf:Item;
}4.循环与迭代的不同
循环适用于需要明确控制循环流程的情况而迭代器则提供了一种更抽象的方式来处理集合元素。通常推荐使用迭代器因为它们可以提高代码的可读性和表达力。
fo循环是一种语法结构用于遍历集合中的元素。它依赖于集合类型实现Iterator trait.
在Rust中迭代器提供了一系列用于遍历集合元素的方法比如next()、mapO、filter)等可以让我们的代码更具有表达性。
Example
fn main() {// loop {// println!(CtrlC);// std::thread::sleep(std::time::Duration::from_secs(1));// }// while循环let mut i 0;while i 10 {println!({}, i);i 1;}println!(for);// for 循环let arr [0, 1, 2, 3, 4, 5, 6, 7, 8];for element in arr {println!({}, element);}// 打印不包括10for i in 0..10 {println!({}, i);}// 打印包括10for i in 0..10 {println!({}, i);}// breaklet arr [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];for element in arr {if element 10 {break;}println!({element});}let arr [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];for element in arr {if element 10 {continue;}println!({element});}outer: loop {println!(outer);loop {println!(inner);// break;break outer; //直接跳出外部的循环}}// 循环的写法let numbers [1, 2, 3, 4, 5];let mut for_numbers Vec::new();for number in numbers.iter() {let item number * number;for_numbers.push(item);}println!(for : {:?}, for_numbers);// 迭代的写法其性能与循环的性能差不多let numbers [1, 2, 3, 4, 5].to_vec();let iter_number: Vec_ numbers.iter().map(|x| x * x).collect();println!(iter : {:?}, iter_number);
}
编译及测试
cargo run Compiling ch12_loop_iter v0.1.0 (/home/wangji/installer/rust/project/ch12_loop_iter)Building [ ] 0/1: ch12_loop_iter(bin) Finished dev profile [unoptimized debuginfo] target(s) in 9.99sRunning target/debug/ch12_loop_iter
0
1
2
3
4
5
6
7
8
9
for
0
1
2
3
4
5
6
7
8
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
11
outer
inner
for : [1, 4, 9, 16, 25]
iter : [1, 4, 9, 16, 25]三、函数基础与Copy值参数传递
1.函数的基础知识
1.函数的定义在Rust中你可以使用fn关键字声明和定义函数而main是程序的入口点是一种特殊的函数。 2.参数和返回值 函数可以接受零个或多个参数每个参数都需要指定类型。 函数可以有返回值使用-指定返回值类型。如果函数没有返回值可以使用-()、或省略这部分。 3.调用函数调用函数时使用函数名和传递给函数的实际参数。
2.Copy by value
如果数据类型实现Copy特质则在函数传参时回实现Copy by value操作。
会将实参拷贝为形参参数改变并不会影响实参。
如果要改变形参需要加上mut
Struct、枚举、集合等并没有实现copy trait会实现move操作失去所有权
为数据类型实现copy trait就可实现copy by value
Example
fn add(x: i32, y: i32) - i32 {x y //直接作为返回值进行返回如果不加;
}fn change_i32(mut x: i32) {x x 4;println!(fn {x});
}// 修改实参
fn modify_i32(x: mut i32) {*x 4;
}#[derive(Copy, Clone)]
struct Point {x: i32,y: i32,
}fn print_point(point: Point) {println!(point x {}, point.x);
}fn main() {let a 1;let b 2;let c add(a, b);println!(c: {c});let mut x 1;change_i32(x);println!(x {x});modify_i32(mut x); //变成可变引用println!(x {x});let s Point { x: 1, y: 2 };print_point(s); // 由于打了标签#[derive(Copy, Clone)]所以可以直接传值println!({}, s.x);
}
编译及运行
cargo runCompiling ch13_fn v0.1.0 (/home/wangji/installer/rust/project/ch13_fn)
warning: field y is never read-- src/main.rs:18:5|
16 | struct Point {| ----- field in this struct
17 | x: i32,
18 | y: i32,| ^| note: Point has a derived impl for the trait Clone, but this is intentionally ignored during dead code analysis note: #[warn(dead_code)] on by defaultwarning: ch13_fn (bin ch13_fn) generated 1 warningFinished dev profile [unoptimized debuginfo] target(s) in 0.56sRunning target/debug/ch13_fn
c: 3
fn 5
x 1
x 5
point x 1
1四、函数值参数的传递、不可变借用参数的传递、可变借用参数的传递
1.函数值参数传递move
函数的代码本身通常是存储在可执行文件的代码段而在调用时函数会在栈开辟一个新的stack frame(栈空间)用于存储函数的局部变量、参数和返回地址等信息而当函数结束后会释放该空间。
而当传入non-Copy value(Vec、String等)传入函数时实参会转移value的所有权给形参实参会失去value的所有权而在函数结束时value的所有权会释放。
2.不可变借用就是C的引用
如果你不想失去value的所有权你又没有修改value的需求你可以使用不可变借用
在Rust中你可以将不可变引用作为函数的参数从而在函数内部访问参数值但不能修改它。这有助于确保数据的安全性防止在多处同时对数据进行写操作从而避免数据竞争。
如何应用不可变借用
Use*to deference去获取其的值
3.可变借用
如果你有修改值的需求你可以使用可变借用以允许在函数内部修改参数的值。这允许函数对参数进行写操作但在同一时间内只能有一个可变引用。
需要在形参前加mut
如何应用可变借用
同样使用Use*to deference,去获取其的值
Example
// p1有默认拷贝
// p2没有默认拷贝所以是move
fn move_func(p1: i32, p2: String) {println!(p1 is {}, p1);println!(p2 is {}, p2);
}// borrow引用但是在这里没意义对于i32这种类型而言
fn print_value(value: i32) {println!({}, value);
}fn string_func_borrow(s: String) {println!({}-{}, (*s).to_uppercase(), s.to_uppercase());
}#[derive(Debug)]
struct Point {x: i32,y: i32,
}fn modify_point(point: mut Point) {(*point).x 2;point.y 2; //等价于(*point).y 2
}fn main() {let n 12;let s String::from(oo);move_func(n, s);println!(n is {}, n);// println!(s is {}, s);let s String::from(oo);print_value(n);print_value(n);string_func_borrow(s);println!(s is {}, s);let mut p Point { x: 0, y: 0 };println!({:?}, p); //就是调用#[derive(Debug)]特质modify_point(mut p);println!({:?}, p);
}
编译及测试
cargo runCompiling ch14_fn_move_borrow_mut v0.1.0 (/home/wangji/installer/rust/project/ch14_fn_move_borrow_mut)Finished dev profile [unoptimized debuginfo] target(s) in 0.28sRunning target/debug/ch14_fn_move_borrow_mut
p1 is 12
p2 is oo
n is 12
12
12
OO-OO
s is oo
Point { x: 0, y: 0 }
Point { x: 2, y: 2 }五、函数返回值与所有权机制
1.返回Copy与Non-Copy
都可以返回但是要注意Non-Copy是在堆上的。
性能
在一般情况下返回Copy类型的值通常具有更好的性能。这是因为Copy类型的值是通过复制进行返回的而不涉及堆上内存的分配和释放通常是在栈上分配。这样的操作比涉及堆上内存额分配和释放更为高效。
2.返回引用
在只有传入一个引用参数只有一个返回引用时生命周期不需要声明
其他情况下需要声明引用的生命周期
慎用‘static
Example
fn func_copy_back() - i32 {let n 42;n
}fn func_non_copy_back() - String {let s String::from(hello);s
}fn get_mess(mark: i32) - static str {if mark 0 {} else {≧ ﹏ ≦}
}fn main() {let i func_copy_back();println!({}, i);let s func_non_copy_back();println!({}, s);println!({}, get_mess(i));
}编译及运行
cargo runCompiling ch15_fn_back v0.1.0 (/home/wangji/installer/rust/project/ch15_fn_back)Finished dev profile [unoptimized debuginfo] target(s) in 10.05sRunning target/debug/ch15_fn_back
42
hello
≧ ﹏ ≦六、高阶函数函数作为参数与返回值
高阶函数Higher-Order FunctionsRust 允许使用高阶函数即函数可以作为参数传递给其他函数或者函数可以返回其他函数。
高阶函数也是函数式编程的重要特性。
1.高阶函数与集合
1、map函数map函数可以用于对一个集合中的每个元素应用一个函数并返回包含结果的新集合。
2、filter函数filter函数用于过滤集合中的元素根据一个谓词函数的返回值。
3、foldfold函数有时也称为reduce^可以用于迭代集合的每个元素并将它们累积到一个单一的结果中。
Example
fn func_twice(f: fn(i32) - i32, x: i32) - i32 {f(f(x))
}fn mul(x: i32) - i32 {x * x
}fn add(x: i32) - i32 {x 10
}fn main() {let result func_twice(mul, 4);println!({result});let res func_twice(add, 10);println!({res});// 数学计算let numbers vec![1, 2, 3, 4, 5, 6, 7];let res: Vec_ numbers.iter().map(|x| x x).collect();println!({:?}, res);// filterlet numbers vec![1, 2, 3, 4, 5, 6, 7];// ref ref_mut movelet evens numbers.into_iter().filter(|x| x % 2 0).collect::Vec_(); //等价于let evens: Vec_println!({:?}, evens);let numbers vec![1, 2, 3, 4, 5, 6, 7]; //构造一个vectorlet sum numbers.iter().fold(0, |acc, x| acc x);println!(Sum: {}, sum);
}
编译及测试
cargo runCompiling ch16_higher_func v0.1.0 (/home/wangji/installer/rust/project/ch16_higher_func)Finished dev profile [unoptimized debuginfo] target(s) in 0.29sRunning target/debug/ch16_higher_func
256
30
[2, 4, 6, 8, 10, 12, 14]
[2, 4, 6]参考
2024 Rust现代实用教程