有没有办法将元素添加到容器,同时不断借用早期元素?

问题描述:

我正在构建一个GUI,我想将所有使用的纹理存储在一个位置,但我必须添加新的纹理,而旧纹理已经永久地借用了。有没有办法将元素添加到容器,同时不断借用早期元素?

let (cat, mouse, dog) = (42, 360, 420); // example values 

let mut container = vec![cat, mouse]; // new container 

let foo = &container[0]; // now container is immutably borrowed 

container.push(dog); // error: mutable borrow 

是否有任何现有结构,允许这样的事情, 或者我可以实现这样的使用原始指针?

绝对最简单的事情是引入共享所有权

use std::rc::Rc; 

fn main() { 
    let (cat, mouse, dog) = (42, 360, 420); 
    let mut container = vec![Rc::new(cat), Rc::new(mouse)]; 
    let foo = container[0].clone(); 
    container.push(Rc::new(dog)); 
} 

现在containerfoo共同拥有cat

是否有任何现有结构,允许这样的事情,

是的,但总有一些权衡。以上,我们使用Rc来分享所有权,这涉及参考计数器。

另一个潜在的解决方案是使用一个舞台:

extern crate typed_arena; 

use typed_arena::Arena; 

fn main() { 
    let container = Arena::new(); 
    let cat = container.alloc(42); 
    let mouse = container.alloc(360); 
    let dog = container.alloc(420); 
} 

这不是可转位,则不能再次参加价值的所有权,并且无​​法删除的值。

能够从集合中删除东西总是使得引用无效危险。

我可以实现这样的使用原始指针

几乎是肯定的。你会说得对吗总是棘手的问题。

,但我必须添加新的结构,而旧的纹理已经不可改变借

很多时候,你不已经做任何这样的事情。例如,你可以将你的逻辑分成几个阶段。你有两个容器;一个人参考,另一个收集新的价值。在阶段结束时,您将两个集合合并为一个。当然,你必须确保在阶段结束后没有引用。