Итак, в моем коде было что-то вроде следующего:
// Trait
trait Shape {
fn area(&self) -> f32;
}
// Rect
struct Rect {
width: f32,
height: f32
}
impl Shape for Rect {
fn area(&self) -> f32 {
self.width * self.height
}
}
// Circle
struct Circle {
radius: f32
}
impl Shape for Circle {
fn area(&self) -> f32 {
self.radius * self.radius * std::f32::consts::PI
}
}
// usage
fn use_shapes(shapes: Vec<Box<dyn Shape>>) {
// ...
}
И мне действительно не нравился Box<dyn ...>
, как по производительности, так и потому, что он был грубым. Мои реализации моей черты были немногочисленны и явны, поэтому я чувствовал себя хорошим кандидатом на получение перечисления.
В процессе преобразования его в перечисление я наткнулся на следующую схему:
// Wrapper enum
enum ShapeEnum {
Rect(Rect),
Circle(Circle)
}
impl Shape for ShapeEnum {
fn area(&self) -> f32 {
match self {
ShapeEnum::Rect(data) => data.area(),
ShapeEnum::Circle(data) => data.area(),
}
}
}
// new usage
fn use_shapes(shapes: Vec<ShapeEnum>) {
// ...
}
Это довольно аккуратно. Это также похоже на обман как-то. Он компилируется и работает, как и ожидалось, просто достаточно необычно, что я хотел посмотреть, есть ли какие-нибудь неожиданные недостатки / затраты / причуды, которых я сейчас не вижу?
Мне также интересно, из-за детерминированный c характер реализации перечисления, это будет хороший макрос? Автоматически генерирует перечисление вокруг признака и набора его разработчиков, который сам реализует признак так же, как версия dyn
.