Rust 基礎(chǔ)系列 #5: Rust 中的函數(shù)
就跟任何現(xiàn)代編程語言一樣,Rust 也有函數(shù)。
你已經(jīng)熟悉的函數(shù)是 main
函數(shù)。這個(gè)函數(shù)在程序啟動(dòng)時(shí)被調(diào)用。
但是其他函數(shù)呢?在本文中,你將學(xué)習(xí)如何在 Rust 程序中使用函數(shù)。
函數(shù)的基本語法
你可能已經(jīng)在我們聲明 main
函數(shù)時(shí)知道了這一點(diǎn),不管怎么樣,還是讓我們看一下聲明函數(shù)的語法。
// 聲明函數(shù)
fn function_name() {
<statement(s)>;
}
// 調(diào)用函數(shù)
function_name();
來讓我們看一個(gè)簡單的函數(shù),它將字符串 "Hi there!"
打印到標(biāo)準(zhǔn)輸出。
fn main() {
greet();
}
fn greet() {
println!("Hi there!");
}
?? 與 C 不一樣的是,不管你是否要在聲明或定義之前調(diào)用函數(shù)都沒有關(guān)系。只要這個(gè)函數(shù)在 某個(gè)地方 被聲明了,Rust 就會(huì)處理它。
正如預(yù)期,它的輸出如下:
Hi there!
這挺簡單的。讓我們把它提升到下一個(gè)級(jí)別。讓我們創(chuàng)建一個(gè)接受參數(shù)并返回值的函數(shù)。有沒有參數(shù)和有沒有返回值這兩者之間無關(guān)。
使用函數(shù)接受參數(shù)
聲明一個(gè)接受參數(shù)的函數(shù)的語法如下:
// 聲明函數(shù)
fn function_name(variable_name: type) {
<statement(s)>;
}
// 調(diào)用函數(shù)
function_name(value);
你可以把函數(shù)參數(shù)想象成一個(gè)傳遞給函數(shù)的 元組。它可以接受多種數(shù)據(jù)類型的參數(shù),而且你可以接受任意多個(gè)參數(shù)。所以,你不必局限于接受相同類型的參數(shù)。
與某些語言不同的是,Rust 沒有 默認(rèn)參數(shù)。在調(diào)用函數(shù)時(shí)填充所有參數(shù)是強(qiáng)制性的。
示例:饑餓函數(shù)
來讓我們看一個(gè)程序來更好地理解這個(gè)。
fn main() {
food(2, 4);
}
fn food(theplas: i32, rotis: i32) {
println!(
"我餓了... 我需要 {} 個(gè)葫蘆巴葉餅和 {} 個(gè)羅提!",
theplas, rotis
);
}
在第 5 行,我聲明了一個(gè)名為 food
的函數(shù)。這個(gè)函數(shù)接受 2 個(gè)參數(shù):theplas
和 rotis
(印度食物的名字)。然后我打印了這些變量的內(nèi)容。
對(duì)于 main
函數(shù),我使用參數(shù) 2
和 4
調(diào)用 food
函數(shù)。這意味著 theplas
被賦值為 2
,rotis
被賦值為 4
。
來讓我們看一下程序的輸出:
我餓了... 我需要 2 個(gè)葫蘆巴葉餅和 4 個(gè)羅提!
我現(xiàn)在真的餓了... ??
從函數(shù)返回值
就像函數(shù)可以接受參數(shù)一樣,函數(shù)也可以返回一個(gè)或多個(gè)值。這樣的函數(shù)的語法如下:
// 聲明函數(shù)
fn function_name() -> data_type {
<statement(s)>;
}
// 調(diào)用函數(shù)
let x = function_name();
函數(shù)可以使用 return
關(guān)鍵字或者使用表達(dá)式而不是語句來返回一個(gè)值。
等等!什么是表達(dá)式?
在進(jìn)一步之前:語句與表達(dá)式
在講解 Rust 函數(shù)的例子中提起這個(gè)可能不太合適,但是你應(yīng)該理解 Rust 和其他編程語言中語句和表達(dá)式的區(qū)別。
語句是以分號(hào)結(jié)尾且 不會(huì)計(jì)算出某個(gè)值 的代碼行。另一方面,表達(dá)式是一行不以分號(hào)結(jié)尾且計(jì)算出某個(gè)值的代碼行。
來讓我們用一個(gè)例子來理解:
fn main() {
let a = 873;
let b = {
// 語句
println!("Assigning some value to b...");
// 表達(dá)式
a * 10
};
println!("b: ");
}
在第 3 行,我開始了一個(gè)代碼塊,在這個(gè)代碼塊中我有一個(gè)語句和一個(gè)表達(dá)式。注釋標(biāo)明了哪個(gè)是哪個(gè)。
在第 5 行的代碼不會(huì)計(jì)算出某個(gè)值,因此需要以分號(hào)結(jié)尾。這是一個(gè)語句。
第 8 行的代碼計(jì)算出了一個(gè)值。它是 a * 10
(873 * 10
),并計(jì)算出了 8730
。因?yàn)檫@一行沒有以分號(hào)結(jié)尾,所以這是一個(gè)表達(dá)式。
?? 使用表達(dá)式是從代碼塊中返回某些東西的一種方便的方法。因此,當(dāng)返回一個(gè)值時(shí),它是
return
關(guān)鍵字的替代方案。表達(dá)式不僅僅用于從函數(shù)中 “返回” 一個(gè)值。正如你剛剛看到的,a * 10
的值是從內(nèi)部作用域 “返回” 到外部作用域,并賦值給變量b
。一個(gè)簡單的作用域不是一個(gè)函數(shù),但表達(dá)式的值仍然被 “返回” 了。
示例:購買腐爛的水果
來讓我們看一個(gè)演示以理解函數(shù)如何返回一個(gè)值:
fn main() {
println!(
"如果我從水果攤買了 2 公斤蘋果,我必須付給他們 {} 印度盧比。",
retail_price(2.0)
);
println!(
"但是,如果我從水果攤買了 30 公斤蘋果,我就要付給他們 {} 印度盧比。",
wholesale_price(30.0)
);
}
fn retail_price(weight: f64) -> f64 {
return weight * 500.0;
}
fn wholesale_price(weight: f64) -> f64 {
weight * 400.0
}
我在上述代碼中有兩個(gè)函數(shù):retail_price
和 wholesale_price
。兩個(gè)函數(shù)都接受一個(gè)參數(shù)并將值存儲(chǔ)在 weight
變量中。這個(gè)變量的類型是 f64
,函數(shù)簽名表示最終函數(shù)返回一個(gè) f64
值。
這兩個(gè)函數(shù)都將購買的蘋果的重量乘以一個(gè)數(shù)字。這個(gè)數(shù)字表示蘋果的當(dāng)前每公斤價(jià)格。由于批發(fā)商有大量訂單,物流在某種程度上更容易,價(jià)格可以降低一點(diǎn)。
除了每公斤價(jià)格之外,這兩個(gè)函數(shù)還有一個(gè)區(qū)別。那就是,retail_price
函數(shù)使用 return
關(guān)鍵字返回乘積。而 wholesale_price
函數(shù)使用表達(dá)式返回乘積。
如果我從水果攤買了 2 公斤蘋果,我必須付給他們 1000 印度盧比。
但是,如果我從水果攤買了 30 公斤蘋果,我就要付給他們 12000 印度盧比。
輸出顯示,從函數(shù)返回值的兩種方法都按預(yù)期工作。
返回多個(gè)值
你可以有一個(gè)返回不同類型的多個(gè)值的函數(shù)。你有很多選擇,但返回一個(gè)元組是最簡單的。
接下來是一個(gè)示例:
fn main() {
let (maths, english, science, sanskrit) = tuple_func();
println!("數(shù)學(xué)考試得分: {maths}");
println!("英語考試得分: {english}");
println!("科學(xué)考試得分: {science}");
println!("梵語考試得分: {sanskrit}");
}
fn tuple_func() -> (f64, f64, f64, f64) {
// return marks for a student
let maths = 84.50;
let english = 85.00;
let science = 75.00;
let sanskrit = 67.25;
(maths, english, science, sanskrit)
}
函數(shù) tuple_func
返回 4 個(gè)封裝在一個(gè)元組中的 f64
值。這些值是一個(gè)學(xué)生在四門科目(滿分 100 分)中獲得的分?jǐn)?shù)。
當(dāng)函數(shù)被調(diào)用時(shí),這個(gè)元組被返回。我可以使用 tuple_name.0
方案打印這些值,但我認(rèn)為最好先解構(gòu)元組,這樣可以幫助我們搞清楚值對(duì)應(yīng)的是什么。然后我使用了包含被解構(gòu)的元組的值的變量來打印分?jǐn)?shù)。
這是我得到的輸出:
數(shù)學(xué)考試得分: 84.5
英語考試得分: 85
科學(xué)考試得分: 75
梵語考試得分: 67.25
總結(jié)
本文介紹了 Rust 編程語言中的函數(shù)。這些是函數(shù)的 “類型”:
- 不接受任何參數(shù)也不返回任何值的函數(shù)
- 接收一個(gè)或多個(gè)參數(shù)的函數(shù)
- 給調(diào)用者返回一個(gè)或多個(gè)值的函數(shù)
你知道接下來是什么嗎?Rust 中的條件語句,也就是 if-else。請(qǐng)繼續(xù)關(guān)注并享受學(xué)習(xí) Rust 的過程。