Rust 基礎系列 #5: Rust 中的函數
在這一章中,在實例的幫助下,學習如何使用函數並從中返回值。
就跟任何現代編程語言一樣,Rust 也有函數。
你已經熟悉的函數是 main
函數。這個函數在程序啟動時被調用。
但是其他函數呢?在本文中,你將學習如何在 Rust 程序中使用函數。
函數的基本語法
你可能已經在我們聲明 main
函數時知道了這一點,不管怎麼樣,還是讓我們看一下聲明函數的語法。
// 聲明函數
fn function_name() {
<statement(s)>;
}
// 調用函數
function_name();
來讓我們看一個簡單的函數,它將字元串 "Hi there!"
列印到標準輸出。
fn main() {
greet();
}
fn greet() {
println!("Hi there!");
}
? 與 C 不一樣的是,不管你是否要在聲明或定義之前調用函數都沒有關係。只要這個函數在 某個地方 被聲明了,Rust 就會處理它。
正如預期,它的輸出如下:
Hi there!
這挺簡單的。讓我們把它提升到下一個級別。讓我們創建一個接受參數並返回值的函數。有沒有參數和有沒有返回值這兩者之間無關。
使用函數接受參數
聲明一個接受參數的函數的語法如下:
// 聲明函數
fn function_name(variable_name: type) {
<statement(s)>;
}
// 調用函數
function_name(value);
你可以把函數參數想像成一個傳遞給函數的 元組。它可以接受多種數據類型的參數,而且你可以接受任意多個參數。所以,你不必局限於接受相同類型的參數。
與某些語言不同的是,Rust 沒有 默認參數。在調用函數時填充所有參數是強制性的。
示例:飢餓函數
來讓我們看一個程序來更好地理解這個。
fn main() {
food(2, 4);
}
fn food(theplas: i32, rotis: i32) {
println!(
"我餓了... 我需要 {} 個葫蘆巴葉餅和 {} 個羅提!",
theplas, rotis
);
}
在第 5 行,我聲明了一個名為 food
的函數。這個函數接受 2 個參數:theplas
和 rotis
(印度食物的名字)。然後我列印了這些變數的內容。
對於 main
函數,我使用參數 2
和 4
調用 food
函數。這意味著 theplas
被賦值為 2
,rotis
被賦值為 4
。
來讓我們看一下程序的輸出:
我餓了... 我需要 2 個葫蘆巴葉餅和 4 個羅提!
我現在真的餓了... ?
從函數返回值
就像函數可以接受參數一樣,函數也可以返回一個或多個值。這樣的函數的語法如下:
// 聲明函數
fn function_name() -> data_type {
<statement(s)>;
}
// 調用函數
let x = function_name();
函數可以使用 return
關鍵字或者使用表達式而不是語句來返回一個值。
等等!什麼是表達式?
在進一步之前:語句與表達式
在講解 Rust 函數的例子中提起這個可能不太合適,但是你應該理解 Rust 和其他編程語言中語句和表達式的區別。
語句是以分號結尾且 不會計算出某個值 的代碼行。另一方面,表達式是一行不以分號結尾且計算出某個值的代碼行。
來讓我們用一個例子來理解:
fn main() {
let a = 873;
let b = {
// 語句
println!("Assigning some value to b...");
// 表達式
a * 10
};
println!("b: {b}");
}
在第 3 行,我開始了一個代碼塊,在這個代碼塊中我有一個語句和一個表達式。注釋標明了哪個是哪個。
在第 5 行的代碼不會計算出某個值,因此需要以分號結尾。這是一個語句。
第 8 行的代碼計算出了一個值。它是 a * 10
(873 * 10
),並計算出了 8730
。因為這一行沒有以分號結尾,所以這是一個表達式。
? 使用表達式是從代碼塊中返回某些東西的一種方便的方法。因此,當返回一個值時,它是
return
關鍵字的替代方案。表達式不僅僅用於從函數中 「返回」 一個值。正如你剛剛看到的,a * 10
的值是從內部作用域 「返回」 到外部作用域,並賦值給變數b
。一個簡單的作用域不是一個函數,但表達式的值仍然被 「返回」 了。
示例:購買腐爛的水果
來讓我們看一個演示以理解函數如何返回一個值:
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
}
我在上述代碼中有兩個函數:retail_price
和 wholesale_price
。兩個函數都接受一個參數並將值存儲在 weight
變數中。這個變數的類型是 f64
,函數簽名表示最終函數返回一個 f64
值。
這兩個函數都將購買的蘋果的重量乘以一個數字。這個數字表示蘋果的當前每公斤價格。由於批發商有大量訂單,物流在某種程度上更容易,價格可以降低一點。
除了每公斤價格之外,這兩個函數還有一個區別。那就是,retail_price
函數使用 return
關鍵字返回乘積。而 wholesale_price
函數使用表達式返回乘積。
如果我從水果攤買了 2 公斤蘋果,我必須付給他們 1000 印度盧比。
但是,如果我從水果攤買了 30 公斤蘋果,我就要付給他們 12000 印度盧比。
輸出顯示,從函數返回值的兩種方法都按預期工作。
返回多個值
你可以有一個返回不同類型的多個值的函數。你有很多選擇,但返回一個元組是最簡單的。
接下來是一個示例:
fn main() {
let (maths, english, science, sanskrit) = tuple_func();
println!("數學考試得分: {maths}");
println!("英語考試得分: {english}");
println!("科學考試得分: {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)
}
函數 tuple_func
返回 4 個封裝在一個元組中的 f64
值。這些值是一個學生在四門科目(滿分 100 分)中獲得的分數。
當函數被調用時,這個元組被返回。我可以使用 tuple_name.0
方案列印這些值,但我認為最好先解構元組,這樣可以幫助我們搞清楚值對應的是什麼。然後我使用了包含被解構的元組的值的變數來列印分數。
這是我得到的輸出:
數學考試得分: 84.5
英語考試得分: 85
科學考試得分: 75
梵語考試得分: 67.25
總結
本文介紹了 Rust 編程語言中的函數。這些是函數的 「類型」:
- 不接受任何參數也不返回任何值的函數
- 接收一個或多個參數的函數
- 給調用者返回一個或多個值的函數
你知道接下來是什麼嗎?Rust 中的條件語句,也就是 if-else。請繼續關注並享受學習 Rust 的過程。
(題圖:MJ/5a07503b-c691-4276-83b2-bb42f5fda347)
via: https://itsfoss.com/rust-functions/
作者:Pratham Patel 選題:lkxed 譯者:Cubik65536 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive