有没有办法在不可变地借用早期元素的同时向容器添加元素?
Is there a way to add elements to a container while immutably borrowing earlier elements?
我正在构建一个 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
.
Is there any kind of existing structure that allows something like this,
是的,但总要权衡取舍。上面,我们使用了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);
}
这是不可索引的,您不能再次获得该值的所有权,也不能删除该值。
能够从集合中删除内容总是使无效引用变得危险。
can I implement something like this using raw pointers
几乎可以肯定。你会不会做对永远是一个棘手的问题。
but I have to add new textures while older textures are already immutably borrowed
很多时候,您没有做任何这样的事情。例如,您可以将逻辑分成多个阶段。你有两个容器;一个是人们参考的,另一个是收集新价值的。在该阶段结束时,您将两个集合合二为一。当然,您必须确保在阶段结束后不使用引用。
我正在构建一个 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
.
Is there any kind of existing structure that allows something like this,
是的,但总要权衡取舍。上面,我们使用了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);
}
这是不可索引的,您不能再次获得该值的所有权,也不能删除该值。
能够从集合中删除内容总是使无效引用变得危险。
can I implement something like this using raw pointers
几乎可以肯定。你会不会做对永远是一个棘手的问题。
but I have to add new textures while older textures are already immutably borrowed
很多时候,您没有做任何这样的事情。例如,您可以将逻辑分成多个阶段。你有两个容器;一个是人们参考的,另一个是收集新价值的。在该阶段结束时,您将两个集合合二为一。当然,您必须确保在阶段结束后不使用引用。