2
votes

This is really hard to explain concisely. But what I want is a struct that has a field of Vec "A" containing a vector of threads with another Vec "B" inside the Vec "A". Vec "A" holds both the Vec "B" and thread handle. Vec "B" has a uniform type, no need for trait objects, but Vec "A" holds multiple different types of Vec "B" using trait objects. Basically I don't want to use trait objects for Vec "B" but use trait objects for Vec "A".

I tried to implement the above but it doesn't always feel right and errors. Is there any actual implementation of this or any direct workaround of this?

I did tried searching it but I feel like I can't word it concisely without writing a short paragraph to Google.

Here's the (pseudo-)code of what I think it should be like:

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

1 Answers

2
votes

So first off, a type alias isn't a new type. Its more like a find and a replace system to help with long type names (Ex: type Foo<T> = FooSys<T, Vec<T>, u32>;). I doubt it will ever allow you to add additional type constraints.

As for your issue, the most direct working interpretation of your pseudo code would be adding a lifetime to the ThreadPool.

trait Tag {}

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


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

However what I assume you really want to know is how to store a Vec of dynamic Vecs containing non-dynamic items. To do this you can use Any and downcast it into the type you want. You can find more info on it in the 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()
    }
}