什么是保持集合中借用值的Rust方式?

时间:2018-04-24 14:56:48

标签: rust

在此:

#[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?

1 个答案:

答案 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);
}