大氣網站背景圖怎么快速推廣自己的產品
文章目錄
- 一、if流程控制與match模式匹配
- 1.流程控制
- 2. IF流程控制
- 3.match 表達式
- 二、循環(huán)與break continue以及與迭代的區(qū)別
- 1.Rust中的循環(huán)Loops
- 2.break && continue
- 3.迭代
- 4.循環(huán)與迭代的不同
- 三、函數(shù)基礎與Copy值參數(shù)傳遞
- 1.函數(shù)的基礎知識
- 2.Copy by value
- 四、函數(shù)值參數(shù)的傳遞、不可變借用參數(shù)的傳遞、可變借用參數(shù)的傳遞
- 1.函數(shù)值參數(shù)傳遞(move)
- 2.不可變借用(就是C++的引用)
- 3.可變借用
- 五、函數(shù)返回值與所有權機制
- 1.返回Copy與Non-Copy
- 2.返回引用
- 六、高階函數(shù):函數(shù)作為參數(shù)與返回值
- 1.高階函數(shù)與集合
- 參考
一、if流程控制與match模式匹配
1.流程控制
Execution Flow(流程)
- 1.代碼執(zhí)行從上倒下Iine-by-line
- 2.而我們執(zhí)行操作時,控制流程可能會改變
主要的流程控制結構
1.順序結構(Sequential Structure):程序按照代碼的順序一步一步執(zhí)行,沒有跳過或循環(huán)。
2.選擇結構(Selection Structure):
-根據(jù)條件選擇不同的路徑執(zhí)行。常見的選擇結構有:
- if語句:根據(jù)條件執(zhí)行不同的代碼塊。
- switchi語句(在某些編程語言中):根據(jù)不同的條件值執(zhí)行不同的代碼塊。
3.循環(huán)結構(Iteration Structure):重復執(zhí)行一段代碼,直到滿足某個條件為止。常見的循環(huán)結構有:
- for循環(huán):按照指定的次數(shù)重復執(zhí)行一段代碼。
- while循環(huán):在條件為真的情況下重復執(zhí)行一段代碼。
- do-while循環(huán):類似于while循環(huán),但是保證至少執(zhí)行一次循環(huán)體。
4.跳轉結構:控制程序的執(zhí)行流程跳轉到指定的位置。常見的跳轉結構有:
- break語句:終止循環(huán)或switch語句的執(zhí)行。
- continue語句:跳過當前循環(huán)中的剩余代碼,進入下一次迭代。
- goto語句(在某些編程語言中):直接跳轉到指定的標簽處。
2. IF流程控制
代碼一行行執(zhí)行
執(zhí)行流程,被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
二、循環(huán)與break continue以及與迭代的區(qū)別
1.Rust中的循環(huán)Loops
Rust提供了幾種循環(huán)結構,其中最常見的是Ioop
、while
和for
。
- 1.Ioop循環(huán):
loop{
///無限循環(huán)的代碼塊
}
Ioop
創(chuàng)建一個無限循環(huán),可以通過break
語句來中斷循環(huán)。
- 2.while循環(huán):
while condition{
//條件為真時執(zhí)行的代碼塊
}
while
循環(huán)在每次迭代之前檢查一個條件,只有在條件為真時才執(zhí)行循環(huán)體。
- 3.
for
循環(huán):
for item in iterable
{//遍歷可迭代對象執(zhí)行的代碼塊
}
for
循環(huán)用于迭代集合或范圍,執(zhí)行代碼塊來處理每個元素。
2.break && continue
·break關鍵字用于立即終止循環(huán),并跳出循環(huán)體
- 可以用于跳出指定標簽循環(huán)
·continue關鍵字用于立即跳過當前循環(huán)中剩余的代碼,直接進入下一次循環(huán)
3.迭代
Rust的迭代主要通過迭代器(iterators)來實現(xiàn)。迭代器是一個抽象,它提供了一種訪問集合元素的統(tǒng)一方式。
從實現(xiàn)上講在Rust中,迭代器是一種實現(xiàn)了Iterator trait的類型!
簡化源碼:
pub trait lterator{type Item;fn next (&mut self)->Option<Self:Item>;
}
4.循環(huán)與迭代的不同
循環(huán)適用于需要明確控制循環(huán)流程的情況,而迭代器則提供了一種更抽象的方式來處理集合元素。通常,推薦使用迭代器,因為它們可以提高代碼的可讀性和表達力。
fo循環(huán)是一種語法結構,用于遍歷集合中的元素。它依賴于集合類型實現(xiàn)Iterator trait.
- 在Rust中,迭代器提供了一系列用于遍歷集合元素的方法,比如next()、mapO、filter)等,可以讓我們的代碼更具有表達性。
Example
fn main() {// loop {// println!("Ctrl+C");// std::thread::sleep(std::time::Duration::from_secs(1));// }// while循環(huán)let mut i = 0;while i < 10 {println!("{}", i);i += 1;}println!("for");// for 循環(huán)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; //直接跳出外部的循環(huán)}}// 循環(huán)的寫法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);// 迭代的寫法,其性能與循環(huán)的性能差不多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]
三、函數(shù)基礎與Copy值參數(shù)傳遞
1.函數(shù)的基礎知識
1.函數(shù)的定義:在Rust中,你可以使用fn關鍵字聲明和定義函數(shù),而main是程序的入口點是一種特殊的函數(shù)。
2.參數(shù)和返回值
函數(shù)可以接受零個或多個參數(shù),每個參數(shù)都需要指定類型。
函數(shù)可以有返回值,使用->
指定返回值類型。如果函數(shù)沒有返回值,可以使用->()、或省略這部分。
3.調用函數(shù):調用函數(shù)時,使用函數(shù)名和傳遞給函數(shù)的實際參數(shù)。
2.Copy by value
如果數(shù)據(jù)類型實現(xiàn)Copy特質,則在函數(shù)傳參時回實現(xiàn)Copy by value操作。
會將實參拷貝為形參,參數(shù)改變并不會影響實參。
如果要改變形參,需要加上mut
Struct、枚舉、集合等并沒有實現(xiàn)copy trait,會實現(xiàn)move操作失去所有權
為數(shù)據(jù)類型實現(xiàn)copy trait,就可實現(xiàn)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
四、函數(shù)值參數(shù)的傳遞、不可變借用參數(shù)的傳遞、可變借用參數(shù)的傳遞
1.函數(shù)值參數(shù)傳遞(move)
函數(shù)的代碼本身通常是存儲在可執(zhí)行文件的代碼段,而在調用時函數(shù)會在棧,開辟一個新的stack frame(??臻g),用于存儲函數(shù)的局部變量、參數(shù)和返回地址等信息,而當函數(shù)結束后會釋放該空間。
而當傳入non-Copy value(Vec、String等)傳入函數(shù)時,實參會轉移value的所有權給形參,實參會失去value的所有權而在函數(shù)結束時,value的所有權會釋放。
2.不可變借用(就是C++的引用)
如果你不想失去value的所有權,你又沒有修改value的需求,你可以使用不可變借用
在Rust中,你可以將不可變引用作為函數(shù)的參數(shù),從而在函數(shù)內部訪問參數(shù)值但不能修改它。這有助于確保數(shù)據(jù)的安全性,防止在多處同時對數(shù)據(jù)進行寫操作,從而避免數(shù)據(jù)競爭。
如何應用不可變借用
- Use*to deference,去獲取其的值
3.可變借用
如果你有修改值的需求你可以使用可變借用,以允許在函數(shù)內部修改參數(shù)的值。這允許函數(shù)對參數(shù)進行寫操作,但在同一時間內只能有一個可變引用。
需要在形參前加&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 }
五、函數(shù)返回值與所有權機制
1.返回Copy與Non-Copy
都可以返回,但是要注意Non-Copy是在堆上的。
性能:
- 在一般情況下,返回Copy類型的值通常具有更好的性能。這是因為Copy類型的值是通過復制進行返回的,而不涉及堆上內存的分配和釋放,通常是在棧上分配。這樣的操作比涉及堆上內存額分配和釋放更為高效。
2.返回引用
在只有傳入一個引用參數(shù),只有一個返回引用時,生命周期不需要聲明
其他情況下需要聲明引用的生命周期
慎用‘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
≧ ﹏ ≦😫
六、高階函數(shù):函數(shù)作為參數(shù)與返回值
高階函數(shù)(Higher-Order Functions):Rust 允許使用高階函數(shù),即函數(shù)可以作為參數(shù)傳遞給其他函數(shù),或者函數(shù)可以返回其他函數(shù)。
高階函數(shù)也是函數(shù)式編程的重要特性。
1.高階函數(shù)與集合
1、map函數(shù):map函數(shù)可以用于對一個集合中的每個元素應用一個函數(shù),并返回包含結果的新集合。
2、filter函數(shù):filter函數(shù)用于過濾集合中的元素,根據(jù)一個謂詞函數(shù)的返回值。
3、fold:fold函數(shù)(有時也稱為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}");// 數(shù)學計算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現(xiàn)代實用教程