首页 > 解决方案 > 如何将特征对象传递给在向量的向量中也具有统一类型的向量?

问题描述

这真的很难简明扼要地解释。但我想要的是一个结构,它有一个 Vec“A”字段,其中包含一个线程向量,在 Vec“A”内有另一个 Vec“B”。Vec "A" 拥有 Vec "B" 和线程句柄。Vec "B" 有一个统一的类型,不需要 trait 对象,但是 Vec "A" 使用 trait 对象拥有多个不同类型的 Vec "B"。基本上我不想对 Vec“B”使用特征对象,而是对 Vec“A”使用特征对象。

我试图实现上述内容,但并不总是感觉正确和错误。是否有任何实际实现或任何直接解决方法?

我确实尝试过搜索它,但我觉得如果不给谷歌写一段简短的文字,我就无法简洁地表达它。

这是我认为应该是什么样的(伪)代码:

trait Tag {}

impl Tag for u32 {}
impl Tag for i64 {}


// Vec "B"
type InnerVec<T: Tag> = Vec<T>;

struct ThreadPool {
    // Vec "A"
    threads: Vec<(JoinHandle<()>, InnerVec<dyn Tag>)>,
}

标签: genericsvectorrusttraitstrait-objects

解决方案


所以首先,类型别名不是新类型。它更像是一个查找和替换系统,以帮助处理长类型名称(例如:)type Foo<T> = FooSys<T, Vec<T>, u32>;。我怀疑它是否会允许您添加额外的类型约束。

至于您的问题,对您的伪代码最直接的工作解释是为ThreadPool.

trait Tag {}

impl Tag for u32 {}
impl Tag for i64 {}


struct ThreadPool<'a> {
    threads: Vec<(JoinHandle<()>, Vec<Box<dyn Tag + 'a>>)>,
}

但是,我假设您真正想知道的是如何存储包含非动态项的动态 Vec 的 Vec。为此,您可以使用Any它并将其向下转换为您想要的类型。您可以在docs中找到有关它的更多信息。

use std::any::Any;

struct ThreadPool {
    threads: Vec<(JoinHandle<()>, Box<dyn Any>)>,
}

impl ThreadPool {
    pub fn get_tags<T: 'static>(&self, index: usize) -> Option<&Vec<T>> {
        let (_, ref boxed) = self.threads[index];
        boxed.downcast_ref()
    }
}

推荐阅读