我對Rust很新,在讀寫the book的同時編寫一些簡單的程序,然後測試我正在學習的內容。由於增加了一個明顯不相關的指令,我的變量的壽命是否會發生變化?
今天我試着寫一個建議作爲練習的程序(更確切地說是最後一個在the end of chapter 8.3)。由於我仍然在學習,因此非常緩慢,因此我幾乎在添加到我的main.rs
的任何新線路上運行新的cargo build
。截至目前,它看起來像這樣:
use std::io::{self, Write};
use std::collections::{HashMap, HashSet};
enum Command<'a> {
Add {name: &'a str, unit: &'a str},
List {unit: &'a str},
Exit
}
fn main() {
let mut units: HashMap<&str, HashSet<&str>> = HashMap::new();
loop {
let mut cmd = String::new();
io::stdin().read_line(&mut cmd).unwrap();
let cmd = match parse_command(&cmd) {
Ok(command) => command,
Err(error) => {
println!("Error: {}!", error);
continue;
}
};
match cmd {
Command::Add {name: new_name, unit: new_unit} => {
let mut u = units.entry("unit1").or_insert(HashSet::new());
u.insert(new_name);
},
Command::List {unit: target_unit} => {},
Command::Exit => break
}
} // end of loop
} // end of main
fn parse_command<'a>(line: &'a String) -> Result<Command<'a>, &'a str> {
Ok(Command::Exit)
// ... still need to write something useful ...
}
沒有什麼複雜的,因爲我還沒有甚至寫我的parse_command
功能,目前只返回一個Result::Ok(Command::Exit)
中做任何事,但是當我嘗試編譯上面的代碼,我得到以下錯誤:
error[E0597]: `cmd` does not live long enough
--> src/main.rs:34:2
|
17 | let cmd = match parse_command(&cmd) {
| --- borrow occurs here
...
34 | } // end of loop
| ^`cmd` dropped here while still borrowed
35 | } // end of main
| - borrowed value needs to live until here
它應該不是什麼奇怪的事情,但我很困惑這個錯誤。是的,我在loop
的末尾放了cmd
,沒關係,但是爲什麼借入的價值需要持續到main
的末尾?與cmd
相關的任何內容都發生在loop
之內,爲什麼借用的值預計會比這更長?
試圖找出什麼是錯的,我刪除了match
臂Command::Add {...}
內的兩條線,所以它看起來是這樣的:
// ...
match cmd {
Command::Add {name: new_name, unit: new_unit} => {},
Command::List {unit: target_unit} => {},
Command::Exit => break
}
// ...
,令我驚訝的是,編譯沒有錯誤的代碼(甚至儘管我需要這些線,所以這只是一個愚蠢的測試)。
我以爲這兩條線有什麼都沒有用我的cmd
做變量,還是他們呢?這裏發生了什麼?我99%確定有一些非常愚蠢的事情,但我無法弄清楚自己可能是什麼。任何幫助將非常感激!
哦......我完全忘了'HashMap的內部偷偷摸摸參考'......非常感謝你的詳細解答!你能否提出一種避免將參考本身放在哈希映射中的好方法?我應該克隆字符串還是類似的東西? –