Làm cách nào để chuyển đối tượng đặc điểm sang một vectơ cũng sẽ có kiểu đồng nhất trong vectơ của vectơ?

Aug 16 2020

Điều này thực sự khó giải thích một cách ngắn gọn. Nhưng những gì tôi muốn là một cấu trúc có một trường Vec "A" chứa một vectơ của các luồng với một Vec "B" khác bên trong Vec "A". Vec "A" giữ cả Vec "B" và xử lý luồng. Vec "B" có một kiểu đồng nhất, không cần đối tượng đặc điểm, nhưng Vec "A" chứa nhiều loại Vec "B" khác nhau bằng cách sử dụng các đối tượng đặc điểm. Về cơ bản, tôi không muốn sử dụng các đối tượng đặc điểm cho Vec "B" mà sử dụng các đối tượng đặc điểm cho Vec "A".

Tôi đã cố gắng thực hiện những điều trên nhưng không phải lúc nào nó cũng cảm thấy đúng và có lỗi. Có bất kỳ triển khai thực tế nào của điều này hoặc bất kỳ giải pháp trực tiếp nào cho việc này không?

Tôi đã cố gắng tìm kiếm nó nhưng tôi cảm thấy như tôi không thể từ nó một cách súc tích nếu không viết một đoạn văn ngắn lên Google.

Đây là mã (giả) của những gì tôi nghĩ nó sẽ như thế này:

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

Trả lời

1 Locke Aug 16 2020 at 07:57

Vì vậy, trước hết, bí danh kiểu không phải là một kiểu mới. Nó giống như một hệ thống tìm và thay thế để trợ giúp với các tên loại dài (Ví dụ type Foo<T> = FooSys<T, Vec<T>, u32>;:). Tôi nghi ngờ rằng nó sẽ cho phép bạn thêm các ràng buộc kiểu bổ sung.

Đối với vấn đề của bạn, cách diễn giải làm việc trực tiếp nhất cho mã giả của bạn sẽ thêm tuổi thọ cho ThreadPool.

trait Tag {}

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


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

Tuy nhiên, điều mà tôi cho rằng bạn thực sự muốn biết là cách lưu trữ một Vec gồm các Vec động có chứa các mục không động. Để làm điều này, bạn có thể sử dụng Anyvà chuyển nó thành loại bạn muốn. Bạn có thể tìm thêm thông tin về nó trong tài liệu .

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