品牌網(wǎng)站模板百度指數(shù)如何分析
Rust之抽空學(xué)習(xí)系列(四)—— 編程通用概念(下)
1、函數(shù)
函數(shù)用來對功能邏輯進(jìn)行封裝,能夠增強(qiáng)復(fù)用、提高代碼的可讀
以下是函數(shù)的主要組成部分:
- 名稱
- 參數(shù)
- 返回類型
- 函數(shù)體
1.1、函數(shù)名稱
在Rust中,函數(shù)通過fn
關(guān)鍵字進(jìn)行聲明,并且函數(shù)的名稱遵循蛇形命名法,即名稱使用小寫字母進(jìn)行組合,單詞與單詞之間使用下劃線進(jìn)行分割,這點倒是和Python中的函數(shù)命名方式倒是相一致的
其實,在Rust中函數(shù)和變量通常都應(yīng)該采用蛇形命名法
維基百科:蛇形命名法
fn make_money() { // 蛇形命名法println!("賺錢");
}fn main() { // 作為入口的main()函數(shù)// 函數(shù)調(diào)用,函數(shù)名加(參數(shù)),現(xiàn)在沒有參數(shù)就是()make_money();
}
剛剛是先定義的函數(shù),再在main
中進(jìn)行調(diào)用,這個順序反過來也不影響,這個可以和某些編程語言的寫法區(qū)分一下
fn main() {make_money();
}
// 放在后面也可以
fn make_money() {println!("賺錢");
}
函數(shù)可以先定義或后定義,只要對于使用區(qū)域可見即可
1.2、函數(shù)參數(shù)
函數(shù)的參數(shù)可以將外部的變化靈活地告訴內(nèi)部的邏輯,在框架不變的前提下隨機(jī)應(yīng)變,作為函數(shù)簽名的一部分,就像在文檔上看到的那樣
fn main() {make_money(3); // 傳入具體的參數(shù)
}fn make_money(times: i32) { // 定義可傳入的參數(shù)println!("賺錢{}次", times);
}
在函數(shù)簽名當(dāng)中,需要顯式聲明每個參數(shù)的類型(Rust的設(shè)計者慎重考慮的結(jié)果),以便于編譯器根據(jù)其他部分的代碼進(jìn)行推導(dǎo)后能明確意圖,顯式地標(biāo)準(zhǔn)總好過復(fù)雜的外部情形,對吧?
而對于需要傳入多個函數(shù)參數(shù)的場景,參數(shù)彼此直接使用,
間隔開即可
fn main() { make_money(3, 100);
}
// 多個參數(shù),指出類型,“,”分隔
fn make_money(times: i32, value: i32) {println!("賺錢{}次, 每次{}", times, value);
}
函數(shù)中的語句和表達(dá)式
先來了解下兩個概念:語句和表達(dá)式
- 語句是執(zhí)行操作但是不返回值的指令
- 表達(dá)式是會進(jìn)行計算并且得到一個值作為結(jié)果的指令
維基百科:語句&語句與表達(dá)式的區(qū)別
這樣看來,表達(dá)式最終還是可以換成某個變量表示的,就像數(shù)學(xué)計算里一樣,我們列了一長串計算的式子,最終的目的也只是為了一個計算結(jié)果
圖中綠框的部分是語句,因為它們沒有返回值,只是在描述一步步地操作,但是第二條語句的右側(cè)紅框部分是一條表達(dá)式,描述了sentence變量與234比較的結(jié)果,最終返回了bool類型
let sentence = 125;let result = {let temp = sentence / 2 ;temp == 234 // 沒有分號,用作表達(dá)式返回
};
還有些復(fù)雜些的場景(比如套{}
的多行語句),在末尾使用表達(dá)式,不帶分號可以返回結(jié)果,因為表達(dá)式不包括分號的部分
1.3、函數(shù)返回值
函數(shù)的返回值也是簽名的一部分,可以向調(diào)用者返回值,使用->
表示,并在其后面聲明其類型
可以使用return
直接返回值或者函數(shù)體中最后一個表達(dá)式的值進(jìn)行返回
fn sum(a: i32, b: i32) -> i32 { // 定義類型a + b // 表達(dá)式返回
}
let result = sum(3, 2); // 返回5
println!("result={}", result);
如果為函數(shù)的表達(dá)式結(jié)果加上分號,那么就會變成語句,進(jìn)而無法匹配返回值類型
可以從報錯信息中看出,此時返回值類型不匹配,現(xiàn)在改成語句后編譯器接收到的是()
,似乎是空元組,那么其實也可以推測出語句默認(rèn)返回的值就是空元組了,這正好對應(yīng)了沒有返回值的函數(shù),其實它們的返回值()
只是沒有體現(xiàn)在代碼中
如果體現(xiàn)出來,可以寫成這樣,沒有返回值的函數(shù)其實也是隱含了一個類型的
2、控制流
程序往往不是平鋪直敘的,需要包含循環(huán)、判斷等控制邏輯使其更加豐滿
2.1、if 表達(dá)式
if
表達(dá)式主要是根據(jù)條件選擇分支,許多的編程語言中都有類似的表達(dá)
let assets = 100;
if assets < 100 { // 條件分支println!("窮人")
} else if assets >= 100 && assets < 10_000 {println!("普通工薪階級")
} else { // 兜底println!("大佬")
}
if
會計算對應(yīng)分支的條件表達(dá)式的bool值,為true則執(zhí)行對應(yīng)的代碼塊的內(nèi)容,為false則將跳過整個代碼塊(Rust不會嘗試將非布爾類型的值轉(zhuǎn)換為布爾類型)
并且,else if
和else
總是伴隨if
,一同組成多條件的分支
接下來,還是需要繼續(xù)強(qiáng)調(diào)一下if
表達(dá)式作為表達(dá)式的屬性,由于if
其實是表達(dá)式,那么本身能夠返回值,因此可以直接將if
的整體判斷和返回內(nèi)容一同放置到值的位置上
let assets = 100;
let identity = if assets < 100 { // 表達(dá)式作為右值"窮人" // 返回值
} else if assets >= 100 && assets < 10_000 { "普通工薪階級"
} else {"大佬"
};
println!("身份={}", identity);
這里對于原來的內(nèi)容進(jìn)行了改寫,將if
判斷結(jié)構(gòu)直接作為賦值語句的右值使用
需要注意的一點是,在使用if
對于條件進(jìn)行判斷的時候,要確保所有分支返回的類型要統(tǒng)一
Rust編譯器需要在編譯的時候確認(rèn)分支返回的類型,需要是某個確定的類型
上圖這種就是一個返回了字符串字面量,而另一個分支是一個整數(shù),顯然不好確定嘛
2.2、循環(huán)
計算機(jī)很擅長做重復(fù)的工作,并且這樣的工作也非常適合它們
在各種編程語言中,提供的循環(huán)的結(jié)構(gòu)也都大同小異,Rust也是基于這些原型進(jìn)行一些優(yōu)化和改造
Rust提供了3種循環(huán):
- loop
- while
- for
2.2.1、loop循環(huán)
使用loop{}
可以定義一段無限循環(huán)
loop {print!("放我出去!")
}
但是,通常我們不會進(jìn)行無意義的無限循環(huán),還是需要滿足一定的條件的時候讓它處理一些事情,這個時候就需要使用break
跳出
let mut i = 1;
let result = loop {i += 1;if i % 3 == 1 {break i; // 滿足條件結(jié)束并返回 4}
};
println!("result={}", result);
2.2.2、while循環(huán)
while循環(huán)會在每次執(zhí)行循環(huán)體之前判斷一次條件,條件為true就執(zhí)行,否則就跳出
let mut num = 10;
while num > 0 {println!("倒數(shù)={}", num);num -= 1;
}
2.2.3、for循環(huán)
使用for
最大的好處是可以方便地遍歷數(shù)組、元組等容器里的元素
let teams = ["姆巴佩", "哈蘭德", "克瓦拉茨赫利亞", "貝林厄姆", "穆德里克"];
println!("開始點名!");
for player in teams.iter() {println!("{}", player);
}
在遍歷元素方面,for
顯得更加安全簡潔
for i in 0 .. teams.len() { // 也可以使用Range通過區(qū)間取出索引println!("{}", i);
}
https://kaisery.github.io/trpl-zh-cn/ch03-05-control-flow.html