MST

星途 面试题库

面试题:Rust结构体方法的高级特性与泛型应用

定义一个泛型结构体`Stack<T>`,它包含一个`Vec<T>`类型的字段`items`。为`Stack<T>`实现以下方法:`push`方法用于将元素压入栈,`pop`方法用于从栈中弹出元素并返回,`peek`方法用于返回栈顶元素的引用但不弹出。另外,实现一个方法`filter`,它接收一个闭包作为参数,该闭包用于判断栈中的元素是否符合特定条件,`filter`方法返回一个新的`Stack<T>`,其中只包含符合条件的元素。要求详细说明泛型类型参数的约束以及生命周期标注,最后在`main`函数中对这些方法进行调用展示。
39.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
// 定义泛型结构体Stack<T>
struct Stack<T> {
    items: Vec<T>,
}

// 为Stack<T>实现方法
impl<T> Stack<T> {
    // push方法:将元素压入栈
    fn push(&mut self, item: T) {
        self.items.push(item);
    }

    // pop方法:从栈中弹出元素并返回
    fn pop(&mut self) -> Option<T> {
        self.items.pop()
    }

    // peek方法:返回栈顶元素的引用但不弹出
    fn peek(&self) -> Option<&T> {
        self.items.last()
    }

    // filter方法:接收闭包,返回只包含符合条件元素的新Stack<T>
    fn filter<F>(&self, f: F) -> Stack<T>
    where
        F: FnMut(&T) -> bool,
    {
        let mut new_stack = Stack { items: Vec::new() };
        for item in self.items.iter() {
            if (f)(item) {
                new_stack.push(item.clone());
            }
        }
        new_stack
    }
}

fn main() {
    let mut stack: Stack<i32> = Stack { items: Vec::new() };

    // 调用push方法
    stack.push(1);
    stack.push(2);
    stack.push(3);

    // 调用pop方法
    let popped = stack.pop();
    println!("Popped: {:?}", popped);

    // 调用peek方法
    let peeked = stack.peek();
    println!("Peeked: {:?}", peeked);

    // 调用filter方法
    let filtered_stack = stack.filter(|&x| x % 2 == 0);
    println!("Filtered Stack Items: {:?}", filtered_stack.items);
}

泛型类型参数的约束以及生命周期标注说明:

  1. 泛型类型参数T
    • 在结构体定义struct Stack<T>impl<T> Stack<T>中,T是一个泛型类型参数,它代表栈中元素的类型。T没有特定的约束,意味着它可以是任何类型,只要这些类型满足在Stack<T>实现的方法中对它们的要求。例如,在filter方法中,T需要实现Clone trait,因为我们在闭包符合条件时使用item.clone()将元素添加到新的栈中。
  2. 闭包参数F
    • filter方法中,F是一个泛型类型参数,代表传入的闭包。F有一个约束F: FnMut(&T) -> bool,这意味着F类型的闭包必须能够接受一个&T类型的引用作为参数,并返回一个bool值。这个约束确保了闭包可以用于判断栈中的元素是否符合特定条件。
  3. 生命周期标注
    • peek方法中,返回类型Option<&T>表示可能返回一个指向栈顶元素的引用。这里没有显式的生命周期标注,因为Rust的生命周期省略规则适用。在这种情况下,返回的引用的生命周期与self的生命周期相关联,因为self是一个&self引用,返回的引用的生命周期不会超过self的生命周期。
    • filter方法中,闭包F接受&T类型的参数,这里的&T引用的生命周期也遵循Rust的生命周期省略规则,它与self的生命周期相关联,因为闭包是在self的上下文中调用的,&T引用的生命周期不会超过self的生命周期。