MST
星途 面试题库

面试题:Rust基元类型与泛型及生命周期的深度结合

编写一个Rust函数,该函数接受一个包含不同基元类型(如i32、f64、bool)的泛型集合,函数需要根据不同的基元类型进行不同的操作(例如对i32进行加法,对f64进行乘法,对bool进行逻辑判断)。同时,确保函数中的引用具有正确的生命周期,避免悬垂引用等问题,详细解释函数中泛型和生命周期的设计思路及实现过程。
29.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
// 定义一个trait,用来抽象不同基元类型的操作
trait PrimitiveOperation {
    fn perform_operation(&self) -> Self;
}

impl PrimitiveOperation for i32 {
    fn perform_operation(&self) -> Self {
        self + 1
    }
}

impl PrimitiveOperation for f64 {
    fn perform_operation(&self) -> Self {
        self * 2.0
    }
}

impl PrimitiveOperation for bool {
    fn perform_operation(&self) -> Self {
        !self
    }
}

// 定义一个泛型函数,接受一个包含不同基元类型的集合
// 这里的生命周期参数 'a 表示集合中的元素至少要和函数调用的生命周期一样长
fn process_collection<T: PrimitiveOperation + 'a>(collection: &'a [T]) -> Vec<T> {
    let mut result = Vec::new();
    for item in collection {
        result.push(item.perform_operation());
    }
    result
}

泛型设计思路及实现过程

  1. 定义 PrimitiveOperation trait:这个trait定义了一个 perform_operation 方法,所有需要在集合中进行操作的基元类型都需要实现这个trait。这样就抽象出了不同基元类型的具体操作,使得泛型函数可以统一调用这个方法。
  2. 为不同基元类型实现 PrimitiveOperation trait:分别为 i32f64bool 实现 perform_operation 方法,定义每种类型具体的操作逻辑。
  3. 定义泛型函数 process_collection:该函数接受一个生命周期为 'a 的切片 &'a [T],这里的 T 是泛型类型参数,要求 T 实现 PrimitiveOperation trait 并且生命周期至少为 'a。这样可以确保函数中对集合元素的操作都是合法的,并且避免悬垂引用问题。在函数内部,遍历集合并调用每个元素的 perform_operation 方法,将结果收集到一个新的 Vec<T> 中返回。

生命周期设计思路及实现过程

  1. 生命周期参数 'a:在泛型函数 process_collection 的参数 collection: &'a [T] 中引入生命周期参数 'a,表示 collection 切片的生命周期为 'a
  2. 约束条件:通过 T: PrimitiveOperation + 'a 约束 T 的生命周期至少为 'a,确保函数内部对 T 类型元素的操作(如调用 perform_operation 方法)在 collection 的生命周期内都是有效的。这样就避免了悬垂引用等问题,因为 T 类型的元素不会在 collection 之前被释放。

你可以这样调用这个函数:

fn main() {
    let int_collection: Vec<i32> = vec![1, 2, 3];
    let int_result = process_collection(&int_collection);
    println!("Int result: {:?}", int_result);

    let float_collection: Vec<f64> = vec![1.0, 2.0, 3.0];
    let float_result = process_collection(&float_collection);
    println!("Float result: {:?}", float_result);

    let bool_collection: Vec<bool> = vec![true, false, true];
    let bool_result = process_collection(&bool_collection);
    println!("Bool result: {:?}", bool_result);
}