存储任何类型的物体在生锈中

发布于 2025-01-22 01:01:12 字数 949 浏览 1 评论 0原文

我想实现一个可以存储任何类型的对象的class 存储。我正在尝试使用特质任何来做到这一点。 存储:: insert ::< t>(键,value)应添加一对,其中键始终是某些string类型,并且该值可以是任何类型。当我存储一个box< hashmap< string,dyn any ny>>编译器说它在编译时没有大小。那么如何避免该错误呢?

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);
        }
    }
}

另外,我不确定是否可以使用std :: Collections :: Hashmap实现此类类

I want to implement a class Storage that can store objects of any types. I am trying to do that using trait Any. The Storage::insert::<T>(key, value) should add a pair, where the key is always some String type, and the value can be any type. When I store a Box<HashMap<String, dyn Any>> the compiler says that it doesn't have size at compile-time. So how can I avoid that error ?

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);
        }
    }
}

Also I'm not sure that such class can be implemented with std::collections::HashMap

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

关于从前 2025-01-29 01:01:12

问题是haspmap&lt; k,v&gt;需要具有大小类型 k k 和v,这不是dyn的情况Any。这意味着必须在编译时知道kv的大小。例如,您始终知道u32将需要32位,但是[u32]的大小事先未知。因此:u32:大小[u32]:!大小

dyn anydyn any也是如此:!大小,因为不同大小的对象可以实现任何,实际上,实际上, 每个对象实现任何。

为了解决这个问题,有一个简单的补丁,它将该类型用box&lt; _&gt;包装。 box是指向堆分配的内存的指针,因此您知道它的大小将始终是指针的大小(粗略地说),并且您无需在编译时知道多少内存您将在堆上分配。在这里:

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

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

The problem is that HaspMap<K, V> needs to have Sized types K and V, which is not the case of dyn Any. This means that the size of K and V must be known at compile time. For instance, you always know that an u32 will take 32 bits, but the size of [u32] is not known beforehand. Therefore: u32: Sized, and [u32]: !Sized.

This is also the case of dyn Any, dyn Any: !Sized, because objects of different size can implement Any, and, in fact, every object implements Any.

To solve this, there is an easy patch, and it's wrapping that type with Box<_>. Box is a pointer to a heap-allocated memory, so you know its size will always be the size of a pointer (roughly speaking), and you don't need to know at compile time how much memory you will allocate on the heap. Here it goes:

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

You will also have to adapt the rest of the code, but you can find everything in the documentation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文