在 Rust 中存储任何类型的对象
Storing objects of any type in Rust
我想实现一个可以存储任何类型对象的 class Storage
。我正在尝试使用 trait Any
来做到这一点。 Storage::insert::<T>(key, value)
应该添加一对,其中键总是一些 String
类型,值可以是任何类型。当我存储 Box<HashMap<String, dyn Any>>
时,编译器说它在编译时没有大小。那么如何避免该错误?
use std::any::{Any, TypeId};
use std::collections::hash_map::Keys;
use std::collections::HashMap;
pub struct Storage where Self: Sized{
map: Box<HashMap<String, dyn Any>>,
}
impl Storage {
pub fn new() -> Self {
Self {
map: Some(Box::new(HashMap::new())),
}
}
pub fn insert<Q: Any>(&mut self, key: &dyn Any, obj: Q) {
if key.is::<String>() {
let key_string = key.downcast_ref::<String>().unwrap();
self.map.as_mut().insert(key_string.clone(), obj);
}
}
}
我也不确定 class 是否可以用 std::collections::HashMap
实现
问题是 HaspMap<K, V>
需要 Sized
类型 K
和 V
,而 dyn Any
则不是。这意味着 K
和 V
的大小必须在编译时已知。例如,您总是知道 u32
将占用 32 位,但事先不知道 [u32]
的大小。因此:u32: Sized
,以及[u32]: !Sized
.
dyn Any
、dyn Any: !Sized
也是如此,因为不同大小的对象都可以实现Any
,而实际上,每个[=38] =] 对象实现 Any
.
为了解决这个问题,有一个简单的补丁,它用 Box<_>
包装那个类型。 Box
是一个指向 heap-allocated 内存的指针,所以你知道它的大小永远是一个指针的大小(粗略地说),你不需要在编译时知道你有多少内存将在堆上分配。开始了:
pub struct Storage {
map: Box<HashMap<String, Box<dyn Any>>>,
}
您还必须调整其余代码,但您可以找到所有内容 in the documentation。
我想实现一个可以存储任何类型对象的 class Storage
。我正在尝试使用 trait Any
来做到这一点。 Storage::insert::<T>(key, value)
应该添加一对,其中键总是一些 String
类型,值可以是任何类型。当我存储 Box<HashMap<String, dyn Any>>
时,编译器说它在编译时没有大小。那么如何避免该错误?
use std::any::{Any, TypeId};
use std::collections::hash_map::Keys;
use std::collections::HashMap;
pub struct Storage where Self: Sized{
map: Box<HashMap<String, dyn Any>>,
}
impl Storage {
pub fn new() -> Self {
Self {
map: Some(Box::new(HashMap::new())),
}
}
pub fn insert<Q: Any>(&mut self, key: &dyn Any, obj: Q) {
if key.is::<String>() {
let key_string = key.downcast_ref::<String>().unwrap();
self.map.as_mut().insert(key_string.clone(), obj);
}
}
}
我也不确定 class 是否可以用 std::collections::HashMap
问题是 HaspMap<K, V>
需要 Sized
类型 K
和 V
,而 dyn Any
则不是。这意味着 K
和 V
的大小必须在编译时已知。例如,您总是知道 u32
将占用 32 位,但事先不知道 [u32]
的大小。因此:u32: Sized
,以及[u32]: !Sized
.
dyn Any
、dyn Any: !Sized
也是如此,因为不同大小的对象都可以实现Any
,而实际上,每个[=38] =] 对象实现 Any
.
为了解决这个问题,有一个简单的补丁,它用 Box<_>
包装那个类型。 Box
是一个指向 heap-allocated 内存的指针,所以你知道它的大小永远是一个指针的大小(粗略地说),你不需要在编译时知道你有多少内存将在堆上分配。开始了:
pub struct Storage {
map: Box<HashMap<String, Box<dyn Any>>>,
}
您还必须调整其余代码,但您可以找到所有内容 in the documentation。