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