有人会友好地向我解释为什么String在这个脚本中使用a 不起作用,但&str确实如此.另外,我如何修改它以便它可以用于String?[版本1.2]
use std::collections::{HashMap};
fn main() {
let mut hash = HashMap::<&str, &str>::new();
hash.insert("this", "value");
let l: &str = "this is a borrowed string reference";
// If the above line was defined as:
//let l: String = "this is a string".to_string();
let mut all = l.split(" ");
let name: &str = all.next().unwrap();
if hash.contains_key(name) == true {
hash.remove(name);
} else {
hash.insert(name, "stuff");
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,让我们把它简化为必需品:
use std::collections::HashMap;
fn main() {
let mut hash = HashMap::<&str, &str>::new();
hash.insert("this", "value");
let l: String = "this is a borrowed string reference".to_string();
hash.insert(&l, "stuff");
}
Run Code Online (Sandbox Code Playgroud)
编译这个给我们:
<anon>:7:18: 7:19 error: `l` does not live long enough
<anon>:7 hash.insert(&l, "stuff");
^
<anon>:4:49: 8:2 note: reference must be valid for the block suffix following statement 0 at 4:48...
<anon>:4 let mut hash = HashMap::<&str, &str>::new();
<anon>:5 hash.insert("this", "value");
<anon>:6 let l: String = "this is a borrowed string reference".to_string();
<anon>:7 hash.insert(&l, "stuff");
<anon>:8 }
<anon>:6:71: 8:2 note: ...but borrowed value is only valid for the block suffix following statement 2 at 6:70
<anon>:6 let l: String = "this is a borrowed string reference".to_string();
<anon>:7 hash.insert(&l, "stuff");
<anon>:8 }
Run Code Online (Sandbox Code Playgroud)
它或多或少地告诉你它究竟不起作用.您尝试将借用的指针插入String l到hashmap中.然而,String根本不够长寿.
具体而言,Rust以反向词汇顺序销毁值.因此,当执行到达函数的末尾时,Rust将l 首先解除分配,然后执行hash.这是一个问题:它意味着有一个窗口,其中hash包含指向已销毁数据的指针,Rust绝对不允许这样做.
这与a一起使用的原因&str是字符串文字"like this"不仅仅是&str; 它实际上是&'static str.这意味着字符串文字在程序的整个持续时间内"存在":它永远不会被破坏,因此hashmap可以安全地保存指向它的指针.
解决方案是确保String遗嘱的寿命HashMap:
use std::collections::HashMap;
fn main() {
// Declare `l` here ...
let l;
let mut hash = HashMap::<&str, &str>::new();
hash.insert("this", "value");
// ... but initialise it *here*.
l = "this is a borrowed string reference".to_string();
hash.insert(&l, "stuff");
}
Run Code Online (Sandbox Code Playgroud)
现在,首先hash被摧毁,然后是.只要在读取或使用它之前对其进行初始化,就可以保留未初始化的变量.l