傳遞參考給函式
參考對函式非常有用。Rust 中關於值的規則是:一個值只能有一個所有者。
這段程式碼將無法運作:
fn print_country(country_name: String) { println!("{}", country_name); } fn main() { let country = String::from("Austria"); print_country(country); // 我們印出 "Austria" print_country(country); // ⚠️ 蠻有趣的,讓我們再做一次! }
它不能運作,因為 country
被銷毀了。它是這麼來的:
- 第一步:我們建立稱為
country
的String
。country
是所有者。 - 第二步:我們把
country
給了print_country
。print_country
沒有->
,所以它不回傳任何東西。在print_country
完成後,我們的String
現在已經死了。 - 第三步:我們嘗試把
country
給print_country
,但我們已經這樣做過了。我們已經沒有country
可以給了。
我們可以讓 print_country
給回 String
,但是有點奇怪。
fn print_country(country_name: String) -> String { println!("{}", country_name); country_name // 這裡回傳它 } fn main() { let country = String::from("Austria"); let country = print_country(country); // 我們現在要在這裡用 let 拿回 String print_country(country); }
現在印出了:
Austria
Austria
更好的解決方式是加上 &
。
fn print_country(country_name: &String) { println!("{}", country_name); } fn main() { let country = String::from("Austria"); print_country(&country); // 我們印出 "Austria" print_country(&country); // 蠻有趣的,讓我們再做一次! }
現在 print_country()
是一個函式,接受 String
的參考:即 &String
。另外,我們寫 &country
來給 country 一個參考,。這表示 "你可以查看它,但我會保有它"。
現在讓我們用一個可變參考來做類似的事情。這是個使用可變變數的函式範例:
fn add_hungary(country_name: &mut String) { // 首先我們說函式接受一個可變參考 country_name.push_str("-Hungary"); // push_str() 加入 &str 到 String println!("Now it says: {}", country_name); } fn main() { let mut country = String::from("Austria"); add_hungary(&mut country); // 我們也要給它可變參考。 }
這印出了 Now it says: Austria-Hungary
。
所以得出結論:
fn function_name(variable: String)
接受String
並擁有它。如果它不回傳任何東西,那麼這個變數就會死在函數裡面。fn function_name(variable: &String)
借用String
並可以查看它fn function_name(variable: &mut String)
借用String
並可以更改
這是個看起來像可變參考但不同的範例。
fn main() { let country = String::from("Austria"); // country 是不可變的,但我們想要印出 Austria-Hungary。怎麼做? adds_hungary(country); } fn adds_hungary(mut country: String) { // 它是這樣做的:adds_hungary 接受 String 並宣告它是可變的! country.push_str("-Hungary"); println!("{}", country); }
這怎麼可能呢?因為 mut country
不是參考。adds_hungary
現在擁有 country
。(記得,它接受的是 String
而不是 &String
)。當你呼叫 adds_hungary
的那一刻,它就完全成了 country 的所有者。country
與 String::from("Austria")
沒有關係了。所以,adds_hungary
可以把 country
當作可變的,這樣做是完全安全的。
還記得前面我們的員工 Powerpoint 和經理的情況嗎?在這種情況下,就好比員工只是把自己的整臺電腦交給了經理。員工不會再碰它,所以經理可以對它做任何他想做的事情。