大氣網(wǎng)站背景圖怎么快速推廣自己的產(chǎn)品
文章目錄
- 一、if流程控制與match模式匹配
- 1.流程控制
- 2. IF流程控制
- 3.match 表達(dá)式
- 二、循環(huán)與break continue以及與迭代的區(qū)別
- 1.Rust中的循環(huán)Loops
- 2.break && continue
- 3.迭代
- 4.循環(huán)與迭代的不同
- 三、函數(shù)基礎(chǔ)與Copy值參數(shù)傳遞
- 1.函數(shù)的基礎(chǔ)知識(shí)
- 2.Copy by value
- 四、函數(shù)值參數(shù)的傳遞、不可變借用參數(shù)的傳遞、可變借用參數(shù)的傳遞
- 1.函數(shù)值參數(shù)傳遞(move)
- 2.不可變借用(就是C++的引用)
- 3.可變借用
- 五、函數(shù)返回值與所有權(quán)機(jī)制
- 1.返回Copy與Non-Copy
- 2.返回引用
- 六、高階函數(shù):函數(shù)作為參數(shù)與返回值
- 1.高階函數(shù)與集合
- 參考
一、if流程控制與match模式匹配
1.流程控制
Execution Flow(流程)
- 1.代碼執(zhí)行從上倒下Iine-by-line
- 2.而我們執(zhí)行操作時(shí),控制流程可能會(huì)改變
主要的流程控制結(jié)構(gòu)
1.順序結(jié)構(gòu)(Sequential Structure):程序按照代碼的順序一步一步執(zhí)行,沒(méi)有跳過(guò)或循環(huán)。
2.選擇結(jié)構(gòu)(Selection Structure):
-根據(jù)條件選擇不同的路徑執(zhí)行。常見(jiàn)的選擇結(jié)構(gòu)有:
- if語(yǔ)句:根據(jù)條件執(zhí)行不同的代碼塊。
- switchi語(yǔ)句(在某些編程語(yǔ)言中):根據(jù)不同的條件值執(zhí)行不同的代碼塊。
3.循環(huán)結(jié)構(gòu)(Iteration Structure):重復(fù)執(zhí)行一段代碼,直到滿足某個(gè)條件為止。常見(jiàn)的循環(huán)結(jié)構(gòu)有:
- for循環(huán):按照指定的次數(shù)重復(fù)執(zhí)行一段代碼。
- while循環(huán):在條件為真的情況下重復(fù)執(zhí)行一段代碼。
- do-while循環(huán):類似于while循環(huán),但是保證至少執(zhí)行一次循環(huán)體。
4.跳轉(zhuǎn)結(jié)構(gòu):控制程序的執(zhí)行流程跳轉(zhuǎn)到指定的位置。常見(jiàn)的跳轉(zhuǎn)結(jié)構(gòu)有:
- break語(yǔ)句:終止循環(huán)或switch語(yǔ)句的執(zhí)行。
- continue語(yǔ)句:跳過(guò)當(dāng)前循環(huán)中的剩余代碼,進(jìn)入下一次迭代。
- goto語(yǔ)句(在某些編程語(yǔ)言中):直接跳轉(zhuǎn)到指定的標(biāo)簽處。
2. IF流程控制
代碼一行行執(zhí)行
執(zhí)行流程,被If(else)改變
可以嵌套使用,但容易引起可讀性問(wèn)題
3.match 表達(dá)式
match
用于模式匹配,允許更復(fù)雜的條件和分支。
可以處理多個(gè)模式,提高代碼的表達(dá)力。
·match
是表達(dá)式,可以返回值。
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表達(dá)式對(duì)比
復(fù)雜性:if
適用于簡(jiǎn)單的條件判斷,而match
更適用于復(fù)雜的模式匹配。
表達(dá)力:match
更靈活,可以處理多個(gè)條件和模式,使代碼更清晰。
返回值:兩者都是表達(dá)式,可以返回值,但match
通常用于更復(fù)雜的場(chǎng)景。
fn main() {let age = 50;if age < 50 {println!("You are young");} else {println!("You are old");}// if 的表達(dá)能力很弱let scores = 70;if scores > 90 {println!("Good!!!");} else if scores > 60 {println!("You are OK!");} else {println!("Bad!!!");}// 類似C++ 三元表達(dá)式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}");
}
編譯及運(yùn)行
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)結(jié)構(gòu),其中最常見(jiàn)的是Ioop
、while
和for
。
- 1.Ioop循環(huán):
loop{
///無(wú)限循環(huán)的代碼塊
}
Ioop
創(chuàng)建一個(gè)無(wú)限循環(huán),可以通過(guò)break
語(yǔ)句來(lái)中斷循環(huán)。
- 2.while循環(huán):
while condition{
//條件為真時(shí)執(zhí)行的代碼塊
}
while
循環(huán)在每次迭代之前檢查一個(gè)條件,只有在條件為真時(shí)才執(zhí)行循環(huán)體。
- 3.
for
循環(huán):
for item in iterable
{//遍歷可迭代對(duì)象執(zhí)行的代碼塊
}
for
循環(huán)用于迭代集合或范圍,執(zhí)行代碼塊來(lái)處理每個(gè)元素。
2.break && continue
·break關(guān)鍵字用于立即終止循環(huán),并跳出循環(huán)體
- 可以用于跳出指定標(biāo)簽循環(huán)
·continue關(guān)鍵字用于立即跳過(guò)當(dāng)前循環(huán)中剩余的代碼,直接進(jìn)入下一次循環(huán)
3.迭代
Rust的迭代主要通過(guò)迭代器(iterators)來(lái)實(shí)現(xiàn)。迭代器是一個(gè)抽象,它提供了一種訪問(wèn)集合元素的統(tǒng)一方式。
從實(shí)現(xiàn)上講在Rust中,迭代器是一種實(shí)現(xiàn)了Iterator trait的類型!
簡(jiǎn)化源碼:
pub trait lterator{type Item;fn next (&mut self)->Option<Self:Item>;
}
4.循環(huán)與迭代的不同
循環(huán)適用于需要明確控制循環(huán)流程的情況,而迭代器則提供了一種更抽象的方式來(lái)處理集合元素。通常,推薦使用迭代器,因?yàn)樗鼈兛梢蕴岣叽a的可讀性和表達(dá)力。
fo循環(huán)是一種語(yǔ)法結(jié)構(gòu),用于遍歷集合中的元素。它依賴于集合類型實(shí)現(xiàn)Iterator trait.
- 在Rust中,迭代器提供了一系列用于遍歷集合元素的方法,比如next()、mapO、filter)等,可以讓我們的代碼更具有表達(dá)性。
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);
}
編譯及測(cè)試:
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ù)基礎(chǔ)與Copy值參數(shù)傳遞
1.函數(shù)的基礎(chǔ)知識(shí)
1.函數(shù)的定義:在Rust中,你可以使用fn關(guān)鍵字聲明和定義函數(shù),而main是程序的入口點(diǎn)是一種特殊的函數(shù)。
2.參數(shù)和返回值
函數(shù)可以接受零個(gè)或多個(gè)參數(shù),每個(gè)參數(shù)都需要指定類型。
函數(shù)可以有返回值,使用->
指定返回值類型。如果函數(shù)沒(méi)有返回值,可以使用->()、或省略這部分。
3.調(diào)用函數(shù):調(diào)用函數(shù)時(shí),使用函數(shù)名和傳遞給函數(shù)的實(shí)際參數(shù)。
2.Copy by value
如果數(shù)據(jù)類型實(shí)現(xiàn)Copy特質(zhì),則在函數(shù)傳參時(shí)回實(shí)現(xiàn)Copy by value操作。
會(huì)將實(shí)參拷貝為形參,參數(shù)改變并不會(huì)影響實(shí)參。
如果要改變形參,需要加上mut
Struct、枚舉、集合等并沒(méi)有實(shí)現(xiàn)copy trait,會(huì)實(shí)現(xiàn)move操作失去所有權(quán)
為數(shù)據(jù)類型實(shí)現(xiàn)copy trait,就可實(shí)現(xiàn)copy by value
Example:
fn add(x: i32, y: i32) -> i32 {x + y //直接作為返回值進(jìn)行返回,如果不加;
}fn change_i32(mut x: i32) {x = x + 4;println!("fn {x}");
}// 修改實(shí)參
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); // 由于打了標(biāo)簽#[derive(Copy, Clone)],所以可以直接傳值println!("{}", s.x);
}
編譯及運(yùn)行:
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ù)的代碼本身通常是存儲(chǔ)在可執(zhí)行文件的代碼段,而在調(diào)用時(shí)函數(shù)會(huì)在棧,開(kāi)辟一個(gè)新的stack frame(棧空間),用于存儲(chǔ)函數(shù)的局部變量、參數(shù)和返回地址等信息,而當(dāng)函數(shù)結(jié)束后會(huì)釋放該空間。
而當(dāng)傳入non-Copy value(Vec、String等)傳入函數(shù)時(shí),實(shí)參會(huì)轉(zhuǎn)移value的所有權(quán)給形參,實(shí)參會(huì)失去value的所有權(quán)而在函數(shù)結(jié)束時(shí),value的所有權(quán)會(huì)釋放。
2.不可變借用(就是C++的引用)
如果你不想失去value的所有權(quán),你又沒(méi)有修改value的需求,你可以使用不可變借用
在Rust中,你可以將不可變引用作為函數(shù)的參數(shù),從而在函數(shù)內(nèi)部訪問(wèn)參數(shù)值但不能修改它。這有助于確保數(shù)據(jù)的安全性,防止在多處同時(shí)對(duì)數(shù)據(jù)進(jìn)行寫操作,從而避免數(shù)據(jù)競(jìng)爭(zhēng)。
如何應(yīng)用不可變借用
- Use*to deference,去獲取其的值
3.可變借用
如果你有修改值的需求你可以使用可變借用,以允許在函數(shù)內(nèi)部修改參數(shù)的值。這允許函數(shù)對(duì)參數(shù)進(jìn)行寫操作,但在同一時(shí)間內(nèi)只能有一個(gè)可變引用。
需要在形參前加&mut
如何應(yīng)用可變借用
- 同樣使用Use*to deference,去獲取其的值
Example:
// p1有默認(rèn)拷貝
// p2沒(méi)有默認(rèn)拷貝,所以是move
fn move_func(p1: i32, p2: String) {println!("p1 is {}", p1);println!("p2 is {}", p2);
}// borrow引用,但是在這里沒(méi)意義,對(duì)于&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; //等價(jià)于(*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); //就是調(diào)用#[derive(Debug)]特質(zhì)modify_point(&mut p);println!("{:?}", p);
}
編譯及測(cè)試:
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ù)返回值與所有權(quán)機(jī)制
1.返回Copy與Non-Copy
都可以返回,但是要注意Non-Copy是在堆上的。
性能:
- 在一般情況下,返回Copy類型的值通常具有更好的性能。這是因?yàn)镃opy類型的值是通過(guò)復(fù)制進(jìn)行返回的,而不涉及堆上內(nèi)存的分配和釋放,通常是在棧上分配。這樣的操作比涉及堆上內(nèi)存額分配和釋放更為高效。
2.返回引用
在只有傳入一個(gè)引用參數(shù),只有一個(gè)返回引用時(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));
}
編譯及運(yùn)行
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ù)可以用于對(duì)一個(gè)集合中的每個(gè)元素應(yīng)用一個(gè)函數(shù),并返回包含結(jié)果的新集合。
2、filter函數(shù):filter函數(shù)用于過(guò)濾集合中的元素,根據(jù)一個(gè)謂詞函數(shù)的返回值。
3、fold:fold函數(shù)(有時(shí)也稱為reduce^)可以用于迭代集合的每個(gè)元素,并將它們累積到一個(gè)單一的結(jié)果中。
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ù)學(xué)計(jì)算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<_>>(); //等價(jià)于let evens: Vec<_>println!("{:?}", evens);let numbers = vec![1, 2, 3, 4, 5, 6, 7]; //構(gòu)造一個(gè)vectorlet sum = numbers.iter().fold(0, |acc, &x| acc + x);println!("Sum: {}", sum);
}
編譯及測(cè)試
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)代實(shí)用教程