面试题答案
一键面试// 定义一个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
}
泛型设计思路及实现过程
- 定义
PrimitiveOperation
trait:这个trait定义了一个perform_operation
方法,所有需要在集合中进行操作的基元类型都需要实现这个trait。这样就抽象出了不同基元类型的具体操作,使得泛型函数可以统一调用这个方法。 - 为不同基元类型实现
PrimitiveOperation
trait:分别为i32
、f64
和bool
实现perform_operation
方法,定义每种类型具体的操作逻辑。 - 定义泛型函数
process_collection
:该函数接受一个生命周期为'a
的切片&'a [T]
,这里的T
是泛型类型参数,要求T
实现PrimitiveOperation
trait 并且生命周期至少为'a
。这样可以确保函数中对集合元素的操作都是合法的,并且避免悬垂引用问题。在函数内部,遍历集合并调用每个元素的perform_operation
方法,将结果收集到一个新的Vec<T>
中返回。
生命周期设计思路及实现过程
- 生命周期参数
'a
:在泛型函数process_collection
的参数collection: &'a [T]
中引入生命周期参数'a
,表示collection
切片的生命周期为'a
。 - 约束条件:通过
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);
}