我正在为一个对象存储开发一个API,我正在努力找到一种在Rust中实现它的方法.这有点令人沮丧,因为我对如何在C++中实现这一点有一个很好的 idea ,所以可能这个设计从根本上不适合Rust ,但我希望这里的人们能够提供一些有用的见解.
我希望能够做到以下几点:
// This is clone & copy
struct Id<Identifiable> {
// What I think would be needed to get this entire system
// to work, but it is not fixed like this so alternate
// ideas are welcome.
raw_id: usize,
_marker: PhantomData<Identifiable>,
}
struct Store {
// ... don't know how to implement this
}
trait Object {
// ... some behavior
}
struct ObjectA {}
impl Object for ObjectA {}
struct ObjectB {}
impl Object for ObjectB {}
impl Store {
pub fn create_object_a(&mut self) -> Id<ObjectA> { todo!() }
pub fn create_object_b(&mut self) -> Id<ObjectB> { todo!() }
pub fn get<'a, Obj: Object(&self, id: Id<Obj>) -> &'a Obj { todo!() }
}
其用途如下:
let store = Store::new();
let handle_a = store.create_object_a();
let handle_b = store.create_object_b();
let obj_a = store.get(handle_a); // obj_a is of type &ObjectA
let obj_b = store.get(handle_b); // obj_b is of type &ObjectB
由于可以放入存储区的具体类型是静态已知的(只有通过create_something()
方法构建时,它们才能在存储区中),我觉得类型系统中应该有足够的信息来实现这一点.我最想避免的一件事是Vec<Box<dyn Any>>
,因为它引入了额外的间接性.
我意识到这在安全防 rust 中是不可能的,尽管我觉得使用不安全防 rust 应该是可能的.我的 idea 是,它在某种程度上类似于Bevy ECS实现存储组件的方式(相同类型的组件连续存储在内存中,我也想在这里看到这一特性),尽管我很难确切地理解它是如何工作的.
希望有人对如何实现这一点有 idea ,或者有一个更好的替代设计.非常感谢.