MST

星途 面试题库

面试题:Rust链式方法调用的泛型与特质应用

编写一个Rust库,实现一个泛型链式调用结构。假设有多个不同类型的操作,每个操作都实现了特定的特质。例如,有一个 `Transformer` 特质用于数据转换,`Validator` 特质用于数据验证。创建一个泛型结构体 `Pipeline`,它可以接受实现了这些特质的不同类型的操作,并通过链式调用的方式按顺序执行这些操作,同时要保证类型安全和灵活性。请详细阐述设计思路并给出完整代码实现。
18.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义特质:分别定义 TransformerValidator 特质,每个特质包含相应的方法。
  2. 泛型结构体 Pipeline:该结构体内部使用 Vec 来存储实现了特质的对象。
  3. 链式调用方法:为 Pipeline 结构体实现添加操作和执行操作的方法,添加操作的方法返回 &mut self 以支持链式调用。

代码实现

// 定义Transformer特质
trait Transformer<T> {
    fn transform(&self, data: T) -> T;
}

// 定义Validator特质
trait Validator<T> {
    fn validate(&self, data: &T) -> bool;
}

// 泛型结构体Pipeline
struct Pipeline<T> {
    operations: Vec<Box<dyn Operation<T>>>,
}

// 定义一个统一的Operation特质,整合Transformer和Validator
trait Operation<T> {
    fn execute(&self, data: &mut T);
}

impl<T> Operation<T> for Box<dyn Transformer<T>> {
    fn execute(&self, data: &mut T) {
        *data = self.transform(*data);
    }
}

impl<T> Operation<T> for Box<dyn Validator<T>> {
    fn execute(&self, data: &mut T) {
        if!self.validate(data) {
            panic!("Validation failed");
        }
    }
}

impl<T> Pipeline<T> {
    // 添加操作的方法
    fn add_operation<O>(&mut self, operation: O)
    where
        O: 'static + Operation<T>,
    {
        self.operations.push(Box::new(operation));
    }

    // 执行操作的方法
    fn execute(&self, mut data: T) -> T {
        for operation in &self.operations {
            operation.execute(&mut data);
        }
        data
    }
}

// 示例实现Transformer
struct ExampleTransformer;
impl<T: std::ops::AddAssign<T>> Transformer<T> for ExampleTransformer {
    fn transform(&self, data: T) -> T {
        let mut new_data = data.clone();
        new_data += new_data;
        new_data
    }
}

// 示例实现Validator
struct ExampleValidator;
impl<T: std::cmp::PartialEq> Validator<T> for ExampleValidator {
    fn validate(&self, data: &T) -> bool {
        *data != Default::default()
    }
}

fn main() {
    let mut pipeline = Pipeline::<i32>::new();
    pipeline.add_operation(ExampleTransformer);
    pipeline.add_operation(ExampleValidator);

    let result = pipeline.execute(5);
    println!("Result: {}", result);
}