Как передать объект-признак в вектор, который также будет иметь однородный тип в векторе вектора?

Aug 16 2020

Это действительно сложно объяснить кратко. Но мне нужна структура, которая имеет поле Vec «A», содержащее вектор потоков с другим Vec «B» внутри Vec «A». Vec «A» удерживает как Vec «B», так и ручку резьбы. Vec «B» имеет единый тип, нет необходимости в объектах-признаках, но Vec «A» содержит несколько различных типов Vec «B», использующих объекты-признаки. По сути, я не хочу использовать объекты-черты для Vec «B», но использую объекты-черты для Vec «A».

Я пытался реализовать вышесказанное, но это не всегда кажется правильным и ошибочным. Есть ли реальная реализация этого или какое-либо прямое решение?

Я попытался найти его, но мне кажется, что я не могу сформулировать его кратко, не написав короткий абзац в Google.

Вот (псевдо) код того, что я думаю:

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

Ответы

1 Locke Aug 16 2020 at 07:57

Итак, во-первых, псевдоним типа не новый тип. Это больше похоже на систему поиска и замены, которая помогает с длинными именами типов (Пример:) 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и преобразовать его в нужный вам тип. Вы можете найти больше информации об этом в документации .

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