ฉันจะส่งผ่านวัตถุลักษณะไปยังเวกเตอร์ที่จะมีประเภทสม่ำเสมอในเวกเตอร์ของเวกเตอร์ได้อย่างไร

Aug 16 2020

นี่เป็นเรื่องยากที่จะอธิบายอย่างกระชับ แต่สิ่งที่ฉันต้องการคือโครงสร้างที่มีเขตข้อมูลของ Vec "A" ที่มีเวกเตอร์ของเธรดที่มี Vec "B" อีกตัวอยู่ใน Vec "A" Vec "A" ถือทั้ง Vec "B" และที่จับด้าย Vec "B" มีรูปแบบเหมือนกันไม่จำเป็นต้องมี trait object แต่ Vec "A" ถือ Vec "B" หลายประเภทโดยใช้ trait object โดยทั่วไปฉันไม่ต้องการใช้ trait objects สำหรับ Vec "B" แต่ใช้ trait objects สำหรับ 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

ก่อนอื่นนามแฝงประเภทไม่ใช่ประเภทใหม่ มากขึ้นเช่นหาและระบบแทนเพื่อช่วยให้มีชื่อชนิดยาว (Ex: type Foo<T> = FooSys<T, Vec<T>, u32>;) ฉันสงสัยว่าจะอนุญาตให้คุณเพิ่มข้อ จำกัด ประเภทเพิ่มเติมได้

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