在此:
#[derive(Debug)]
struct Person {
name: String,
}
fn main() {
let mut persons = Vec::<Person>::with_capacity(3);
let mut personrefs = Vec::<&Person>::with_capacity(persons.capacity());
for x in 0..persons.capacity() {
let person = Person {
name: format!("Alice-{}", x),
};
personrefs.push(&person);
persons.push(person);
}
println!("persons are {:#?}", persons);
}
我有点理解为什么Rust不允许推&person
,但Rust解决这个问题的方法是什么?
我有Vec
“拥有”Person
s,但我还想将人员映射到其他一些数据而不触及拥有Vec
或重复{{1}在记忆中。比如,有一个Person
。如果collections::HashMap<&Person, SomeOtherData>
和HashMap
的生命周期相同,那么Rust不会知道何时解除分配Vec
s?
答案 0 :(得分:5)
&#34; Rust方式&#34;是不会导致记忆不安全的方式。您的代码无效,正如编译器告诉您的那样:
error[E0597]: `person` does not live long enough
--> src/main.rs:13:26
|
13 | personrefs.push(&person);
| ^^^^^^ borrowed value does not live long enough
14 | persons.push(person);
15 | }
| - `person` dropped here while still borrowed
16 | println!("persons are {:#?}", persons);
17 | }
| - borrowed value needs to live until here
您正在循环中创建Person
,引用它,然后将Person
移动到新的内存地址,使引用无效。如果你访问了那个引用,你就会触及未定义的内存,导致最好的段错误或者#34;奇怪的行为&#34; /最坏的安全漏洞。
同样,您无法将此人添加到Vec
,然后在循环中引用该人,因为循环的后续迭代将使该向量发生变异。当您推送向量时,它可能会重新分配内存,再次使您的引用无效。
我将此代码编写为
fn main() {
let persons: Vec<_> = (0..3)
.map(|x| Person {
name: format!("Alice-{}", x),
})
.collect();
let personrefs: Vec<_> = persons.iter().collect();
println!("persons are {:#?}", persons);
}