面试题答案
一键面试使用Rust语言实现如下:
- 定义
trait
和结构体
// 定义Shape trait
trait Shape {
fn area(&self) -> f64;
}
// 定义Circle结构体
struct Circle {
radius: f64,
}
impl Shape for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
// 定义Rectangle结构体
struct Rectangle {
width: f64,
height: f64,
}
impl Shape for Rectangle {
fn area(&self) -> f64 {
self.width * self.height
}
}
// 定义Triangle结构体
struct Triangle {
base: f64,
height: f64,
}
impl Shape for Triangle {
fn area(&self) -> f64 {
0.5 * self.base * self.height
}
}
- 计算总面积的基本函数
fn total_area(shapes: &[&dyn Shape]) -> f64 {
shapes.iter().map(|shape| shape.area()).sum()
}
- 使用函数指针和闭包实现灵活的面积计算策略
// 定义一个面积修正函数指针类型
type AreaModifier = fn(f64) -> f64;
// 使用函数指针实现灵活计算
fn total_area_with_modifier(shapes: &[&dyn Shape], modifier: AreaModifier) -> f64 {
shapes.iter().map(|shape| (modifier)(shape.area())).sum()
}
// 使用闭包实现灵活计算
fn total_area_with_closure(shapes: &[&dyn Shape], closure: impl Fn(f64) -> f64) -> f64 {
shapes.iter().map(|shape| closure(shape.area())).sum()
}
代码复用的关键思路和实现细节:
-
关键思路:
- Trait 抽象:通过定义
Shape
trait,将不同图形的面积计算方法统一抽象出来。这样,不同的图形结构体只需要实现Shape
trait 中的area
方法,就可以在统一的接口下进行操作。 - 函数指针和闭包:它们提供了一种灵活的方式来对面积计算结果进行进一步处理。函数指针和闭包可以作为参数传递给计算总面积的函数,这样在不改变原有图形面积计算逻辑的基础上,能够对不同类型图形的面积应用不同的修正策略。
- Trait 抽象:通过定义
-
实现细节:
- Trait 对象集合:
total_area
函数接收一个&[&dyn Shape]
类型的参数,即Shape
trait 对象的切片。这样可以将不同类型但都实现了Shape
trait 的图形对象统一收集起来进行操作。 - 函数指针:定义了
AreaModifier
类型别名,它是一个函数指针类型,接收一个f64
类型的面积值,返回一个f64
类型的修正后面积值。total_area_with_modifier
函数接收这样的函数指针作为参数,并在计算总面积时应用这个函数指针来修正每个图形的面积。 - 闭包:
total_area_with_closure
函数接收一个实现了Fn(f64) -> f64
trait 的闭包作为参数。闭包在灵活性上比函数指针更强,它可以捕获环境变量。在计算总面积时,同样应用闭包来修正每个图形的面积。
- Trait 对象集合:
在实际使用时,可以这样调用:
fn main() {
let circle = Circle { radius: 5.0 };
let rectangle = Rectangle { width: 4.0, height: 3.0 };
let triangle = Triangle { base: 6.0, height: 4.0 };
let shapes: Vec<&dyn Shape> = vec![&circle, &rectangle, &triangle];
let total = total_area(&shapes);
println!("Total area: {}", total);
// 使用函数指针
let modifier: AreaModifier = |area| area * 2.0;
let total_with_modifier = total_area_with_modifier(&shapes, modifier);
println!("Total area with modifier: {}", total_with_modifier);
// 使用闭包
let total_with_closure = total_area_with_closure(&shapes, |area| area * 3.0);
println!("Total area with closure: {}", total_with_closure);
}
这段代码实现了对不同类型图形面积的统一计算,并且通过函数指针和闭包实现了灵活的面积修正策略,同时展示了代码复用的关键要点。