在 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 类型 KV,而 dyn Any 则不是。这意味着 KV 的大小必须在编译时已知。例如,您总是知道 u32 将占用 32 位,但事先不知道 [u32] 的大小。因此:u32: Sized,以及[u32]: !Sized.

dyn Anydyn Any: !Sized也是如此,因为不同大小的对象都可以实现Any,而实际上,每个[=38] =] 对象实现 Any.

为了解决这个问题,有一个简单的补丁,它用 Box<_> 包装那个类型。 Box 是一个指向 heap-allocated 内存的指针,所以你知道它的大小永远是一个指针的大小(粗略地说),你不需要在编译时知道你有多少内存将在堆上分配。开始了:

pub struct Storage {
  map: Box<HashMap<String, Box<dyn Any>>>,
}

您还必须调整其余代码,但您可以找到所有内容 in the documentation