好的,让我们把重点放在必要的事情上:
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");
}
编译这个代码会得到以下结果:
<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 }
这段话大致意思是:当你试图将一个借用的指向字符串 l 的指针插入哈希表时,会发现这个字符串并没有活得足够久。具体来说,Rust 按照反向词法顺序销毁值。因此,在函数执行到末尾时,Rust 首先释放 l,然后是 hash。这是一个问题:这意味着在 hash 包含对已销毁数据的指针的窗口期间,Rust 绝对不允许这种情况发生。使用 &str 的原因是字符串字面量 "like this" 不仅仅是 &str 类型;它实际上是 &'static str 类型。这意味着字符串字面量在整个程序的生命周期内都存在:它永远不会被销毁,因此哈希表可以安全地持有指向它的指针。解决方法是确保 String 活得比 HashMap 更长。
use std::collections::HashMap;
fn main() {
let l;
let mut hash = HashMap::<&str, &str>::new();
hash.insert("this", "value");
l = "this is a borrowed string reference".to_string();
hash.insert(&l, "stuff");
}
现在,首先销毁
hash
,然后是
l
。变量未初始化也没关系,只要在读取或使用之前进行初始化即可。