dyn - 动态分发 trait 对象
dyn
是关键字,用于指示一个类型是动态分发(dynamic dispatch),也就是说,它是通过trait object实现的。这意味着这个类型在编译期间不确定,只有在运行时才能确定。
- practice
trait object实现多态性。
假设有一个几何图形的类层次结构,例如圆形(Circle)和矩形(Rectangle),每种几何图形都有一个计算面积的方法。定义trait Shape
来表示这个特征,并在每个几何图形中实现这个trait。
trait Shape {
fn area(&self) -> f64;
}
struct Circle {
radius: f64,
}
impl Shape for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
struct Rectangle {
width: f64,
height: f64,
}
impl Shape for Rectangle {
fn area(&self) -> f64 {
self.width * self.height
}
}
现在编写一个函数,可以计算不同类型几何图形的总面积。我们可以使用trait object来实现这个函数:
fn total_area(shapes: &[&dyn Shape]) -> f64 {
let mut total = 0.0;
for shape in shapes {
total += shape.area();
}
total
}
&[&dyn Shape]
类型的参数来接受几何图形的数组。数组中的每个元素都是一个对实现Shape
trait的具体类型的引用。使用for
循环遍历这个数组,并对每个元素调用area
方法,计算它的面积,并将结果累加到总面积中。
创建一些具体的几何图形实例,并将它们传递给total_area
函数,以计算它们的总面积:
fn main() {
let shapes: Vec<&dyn Shape> = vec![
&Circle {
radius: 1.0 },
&Rectangle {
width: 3.0, height: 4.0 },
//&Circle { radius: 1.5 },
];
let total = total_area(&shapes);
println!("Total area: {}", total);
}
输出结果正确: