MST

星途 面试题库

面试题:Rust特征对象与泛型在异步编程中的深度融合

在Rust的异步编程环境下,使用特征与泛型实现一个通用的异步任务调度器。定义一个`AsyncTask`特征,它有一个异步执行方法`execute`。再定义一个泛型类型`TaskQueue<T>`,其中`T: AsyncTask`,实现一个`schedule`方法,该方法将任务添加到队列中并按顺序异步执行这些任务。需要考虑如何高效地管理任务执行过程中的资源,以及如何处理异步操作可能产生的错误。请详细说明你的设计思路,并给出关键代码片段。
18.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义 AsyncTask 特征:包含一个异步执行方法 execute,所有需要调度执行的任务类型都要实现这个特征。
  2. 定义 TaskQueue<T> 泛型类型T 限定为实现了 AsyncTask 特征的类型。该类型内部使用一个队列来存储任务。
  3. 实现 schedule 方法:将任务添加到队列中,并按顺序异步执行这些任务。在执行过程中,使用 futures 库来管理异步操作,利用 tokio 等运行时来实际执行异步任务。通过 Result 类型来处理异步操作可能产生的错误。

关键代码片段

use std::collections::VecDeque;
use futures::future::Future;
use tokio::task::spawn;

// 定义 AsyncTask 特征
pub trait AsyncTask {
    async fn execute(&self) -> Result<(), Box<dyn std::error::Error>>;
}

// 定义 TaskQueue 泛型类型
pub struct TaskQueue<T>
where
    T: AsyncTask,
{
    tasks: VecDeque<T>,
}

impl<T> TaskQueue<T>
where
    T: AsyncTask,
{
    // 构造函数
    pub fn new() -> Self {
        TaskQueue {
            tasks: VecDeque::new(),
        }
    }

    // 将任务添加到队列
    pub fn enqueue(&mut self, task: T) {
        self.tasks.push_back(task);
    }

    // 按顺序异步执行任务
    pub async fn schedule(&mut self) {
        while let Some(task) = self.tasks.pop_front() {
            match spawn(task.execute()).await {
                Ok(Ok(())) => (),
                Ok(Err(e)) => eprintln!("Task execution error: {}", e),
                Err(e) => eprintln!("Task spawn error: {}", e),
            }
        }
    }
}

示例使用

// 示例任务类型
struct ExampleTask;

impl AsyncTask for ExampleTask {
    async fn execute(&self) -> Result<(), Box<dyn std::error::Error>> {
        println!("Executing ExampleTask");
        Ok(())
    }
}

#[tokio::main]
async fn main() {
    let mut task_queue = TaskQueue::<ExampleTask>::new();
    task_queue.enqueue(ExampleTask);
    task_queue.schedule().await;
}