面试题答案
一键面试-
设计思路:
- 在Rust中,当一个对象被传递给函数时,函数会获取该对象的所有权,除非使用引用。为了确保内存安全和高效,我们需要根据对象的生命周期和使用方式来决定是传递所有权还是引用。
- 如果函数需要在操作后销毁对象,那么传递所有权是合适的;如果函数只是读取对象的内容而不修改或销毁它,传递不可变引用比较好;如果函数需要修改对象,传递可变引用。
- 对于图形绘制系统,不同的用户操作可能有不同的需求。例如,绘制操作可能只需要读取图形对象,而删除操作可能需要获取对象的所有权。
-
关键代码片段:
// 定义Point结构体
struct Point {
x: f64,
y: f64,
}
// 定义Shape trait
trait Shape {
fn draw(&self);
}
// 定义Circle结构体并实现Shape trait
struct Circle {
center: Point,
radius: f64,
}
impl Shape for Circle {
fn draw(&self) {
println!("Drawing a circle at ({}, {}) with radius {}", self.center.x, self.center.y, self.radius);
}
}
// 定义Rectangle结构体并实现Shape trait
struct Rectangle {
top_left: Point,
bottom_right: Point,
}
impl Shape for Rectangle {
fn draw(&self) {
println!("Drawing a rectangle from ({}, {}) to ({}, {})", self.top_left.x, self.top_left.y, self.bottom_right.x, self.bottom_right.y);
}
}
// 函数:绘制图形(使用不可变引用,因为只是读取图形信息)
fn draw_shape(shape: &impl Shape) {
shape.draw();
}
// 函数:删除图形(获取所有权,因为需要销毁图形对象)
fn delete_shape(shape: Box<dyn Shape>) {
drop(shape);
}
- 使用示例:
fn main() {
let circle = Box::new(Circle {
center: Point { x: 0.0, y: 0.0 },
radius: 5.0,
});
let rectangle = Box::new(Rectangle {
top_left: Point { x: 1.0, y: 1.0 },
bottom_right: Point { x: 3.0, y: 3.0 },
});
// 绘制图形
draw_shape(&*circle);
draw_shape(&*rectangle);
// 删除图形
delete_shape(circle);
delete_shape(rectangle);
}
在上述代码中:
draw_shape
函数接受一个实现了Shape
trait的不可变引用,这适合于仅读取图形属性进行绘制的操作。delete_shape
函数接受一个实现了Shape
trait的Box
类型对象(获取所有权),适合于需要销毁图形对象的操作。Box<dyn Shape>
表示一个指向实现了Shape
trait的动态类型对象的指针,通过drop
函数(在delete_shape
函数结束时隐式调用)来释放对象的内存。