Jak przekazać obiekt cechy do wektora, który również będzie miał jednolity typ w wektorze wektora?

Aug 16 2020

Naprawdę trudno to zwięźle wyjaśnić. Ale to, czego chcę, to struktura, która ma pole Vec „A” zawierające wektor wątków z innym Vec „B” wewnątrz Vec „A”. Vec "A" trzyma zarówno Vec "B", jak i uchwyt gwintu. Vec „B” ma jednolity typ, nie ma potrzeby stosowania obiektów cech, ale Vec „A” posiada wiele różnych typów Vec „B” używających obiektów cech. Zasadniczo nie chcę używać obiektów cech dla Vec „B”, ale używam obiektów cech dla Vec „A”.

Próbowałem wdrożyć powyższe, ale nie zawsze wydaje się to dobre i błędy. Czy istnieje rzeczywista implementacja tego lub bezpośrednie obejście tego problemu?

Próbowałem to przeszukać, ale czuję, że nie mogę wyrazić tego zwięźle bez napisania krótkiego akapitu do Google.

Oto (pseudo) kod tego, co moim zdaniem powinno wyglądać:

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

Odpowiedzi

1 Locke Aug 16 2020 at 07:57

Po pierwsze, alias typu nie jest nowym typem. To bardziej przypomina system znajdowania i zastępowania, który pomaga przy długich nazwach typów (np .:) type Foo<T> = FooSys<T, Vec<T>, u32>;. Wątpię, czy kiedykolwiek pozwoli ci to na dodanie dodatkowych ograniczeń typu.

Jeśli chodzi o twój problem, najbardziej bezpośrednią interpretacją roboczą twojego pseudokodu byłoby dodanie okresu istnienia do ThreadPool.

trait Tag {}

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


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

Jednak zakładam, że naprawdę chcesz wiedzieć, jak przechowywać Vec dynamicznych VEC zawierających elementy niedynamiczne. Aby to zrobić, możesz użyć Anyi obniżyć go do żądanego typu. Więcej informacji na ten temat można znaleźć w dokumentacji .

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