Comment passer un objet trait à un vecteur qui aura également un type uniforme dans le vecteur du vecteur?

Aug 16 2020

C'est vraiment difficile à expliquer de manière concise. Mais ce que je veux, c'est une structure qui a un champ de Vec "A" contenant un vecteur de threads avec un autre Vec "B" à l'intérieur du Vec "A". Vec "A" tient à la fois le Vec "B" et la poignée de filetage. Vec "B" a un type uniforme, pas besoin d'objets de trait, mais Vec "A" contient plusieurs types différents de Vec "B" utilisant des objets de trait. Fondamentalement, je ne veux pas utiliser d'objets de trait pour Vec "B" mais utiliser des objets de trait pour Vec "A".

J'ai essayé de mettre en œuvre ce qui précède mais cela ne me semble pas toujours correct et des erreurs. Existe-t-il une implémentation réelle de ceci ou une solution de contournement directe à cela?

J'ai essayé de le rechercher, mais j'ai l'impression de ne pas pouvoir le formuler de manière concise sans écrire un court paragraphe à Google.

Voici le (pseudo-) code de ce à quoi je pense que cela devrait ressembler:

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

Réponses

1 Locke Aug 16 2020 at 07:57

Donc, tout d'abord, un alias de type n'est pas un nouveau type. Cela ressemble plus à un système de recherche et de remplacement pour aider avec les noms de type longs (Ex:) type Foo<T> = FooSys<T, Vec<T>, u32>;. Je doute que cela vous permette jamais d'ajouter des contraintes de type supplémentaires.

En ce qui concerne votre problème, l'interprétation la plus directe de votre pseudo-code consisterait à ajouter une durée de vie au fichier ThreadPool.

trait Tag {}

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


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

Cependant, je suppose que vous voulez vraiment savoir comment stocker un Vec de Vecs dynamiques contenant des éléments non dynamiques. Pour ce faire, vous pouvez l'utiliser Anyet le réduire dans le type souhaité. Vous pouvez trouver plus d'informations à ce sujet dans la documentation .

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