是否有一种惯用的方法来保持对不断增长的容器元素的引用?

chs*_*chs 1 lifetime rust borrow-checker

我正在尝试为类型的对象编写容器,该容器T提供&T对存储对象的引用的访问(我想避免复制).由于容器只在其生命周期内增长,因此返回引用的生命周期&T应与容器的生命周期相同.

到目前为止,我最接近的是Box<T>在容器内部使用对象并用于Box<T>.as_ref()返回对这些对象的引用.然而,然而,我遇到了与此最小示例中相同的问题:

fn main() {
    let mut v = vec![Box::new(1)]; // line 1
    let x = v[0].as_ref();         // line 2: immutable borrow occurs here
    println!("x = {:?}", x);       // line 3
    v.push(Box::new(2));           // line 4: mutable borrow occurs here -> error
    println!("x = {:?}", x);       // line 5
}
Run Code Online (Sandbox Code Playgroud)

据我所知,x如果v在可变借款期间删除了它,那么在第5行使用是不合理的.但这不是这里的情况,它永远不会是我的容器.如果没有安全的方法在Rust中表达这一点,我怎么能"修复"这个例子(没有复制x)?

Chr*_*son 5

正如@ ker的回答所说,仅仅因为你只增长了一个容器并不意味着引用保持有效,因为内存可以重新分配.

如果你只是增长容器的另一个解决方案是只存储索引而不是引用:

fn main() {
    let mut v = vec!["Foo"];    // line 1
    let x = 0;                  // line 2: just store an index.
    println!("x = {:?}", v[x]); // Use the index as needed
    v.push("bar");              // line 4: No problem, there are no references.
    println!("x = {:?}", v[x]); // line 5: use the index again.
}
Run Code Online (Sandbox Code Playgroud)