我对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的内部偷偷摸摸参考'......非常感谢你的详细解答!你能否提出一种避免将参考本身放在哈希映射中的好方法?我应该克隆字符串还是类似的东西? –