¿Cómo paso un objeto de rasgo a un vector que también tendrá un tipo uniforme en el vector del vector?

Aug 16 2020

Esto es realmente difícil de explicar de forma concisa. Pero lo que quiero es una estructura que tenga un campo de Vec "A" que contenga un vector de subprocesos con otro Vec "B" dentro del Vec "A". Vec "A" sostiene tanto el Vec "B" como el mango de rosca. Vec "B" tiene un tipo uniforme, sin necesidad de objetos de rasgo, pero Vec "A" contiene varios tipos diferentes de Vec "B" usando objetos de rasgo. Básicamente, no quiero usar objetos de rasgo para Vec "B", sino usar objetos de rasgo para Vec "A".

Intenté implementar lo anterior, pero no siempre se siente bien y hay errores. ¿Existe alguna implementación real de esto o alguna solución alternativa directa a esto?

Intenté buscarlo, pero siento que no puedo redactarlo de manera concisa sin escribir un breve párrafo en Google.

Aquí está el (pseudo-) código de lo que creo que debería ser:

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

Respuestas

1 Locke Aug 16 2020 at 07:57

En primer lugar, un alias de tipo no es un tipo nuevo. Es más como un sistema de búsqueda y reemplazo para ayudar con nombres de tipos largos (Ej:) type Foo<T> = FooSys<T, Vec<T>, u32>;. Dudo que alguna vez le permita agregar restricciones de tipo adicionales.

En cuanto a su problema, la interpretación de trabajo más directa de su pseudocódigo sería agregar una vida útil al ThreadPool.

trait Tag {}

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


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

Sin embargo, lo que supongo que realmente desea saber es cómo almacenar un Vec de Vecs dinámicos que contengan elementos no dinámicos. Para hacer esto, puede usarlo Anyy convertirlo en el tipo que desee. Puede encontrar más información al respecto en los documentos .

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