谁能给我解释一下为什么在此脚本中使用 String
不起作用,而 &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");
}
}
最佳答案
好吧,让我们把它归结为必需品:
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 }
这或多或少地告诉您确切什么是行不通的。您尝试将指向 String
l
的借用指针插入 HashMap 中。然而,String
的生命周期不够长。
具体来说,Rust 以相反的词法顺序销毁值。因此,当执行到函数末尾时,Rust 将释放 l
first,然后是 hash
。这是一个问题:这意味着有一个窗口,在此期间 hash
包含指向已销毁数据的指针,这是 Rust 绝对不允许的。
这与 &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");
}
现在,hash
首先被销毁,然后是 l
。保留一个未初始化的变量是可以的,只要您在读取或使用它之前对其进行初始化即可。
关于rust - 如何在迭代器中使用字符串而不是 &str,if/else block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32119978/