有没有办法将元素添加到容器,同时不断借用早期元素?
问题描述:
我正在构建一个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));
}
现在container
和foo
共同拥有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);
}
这不是可转位,则不能再次参加价值的所有权,并且无法删除的值。
能够从集合中删除东西总是使得引用无效危险。
我可以实现这样的使用原始指针
几乎是肯定的。你会说得对吗总是棘手的问题。
,但我必须添加新的结构,而旧的纹理已经不可改变借
很多时候,你不已经做任何这样的事情。例如,你可以将你的逻辑分成几个阶段。你有两个容器;一个人参考,另一个收集新的价值。在阶段结束时,您将两个集合合并为一个。当然,你必须确保在阶段结束后没有引用。