Это выглядит как идеальный случай для generics.
Вы можете сделать одну-структуру, как это:
struct ShapeRenderer<T: Shape> {
canvas: Canvas,
origin: Point,
shape: T,
}
Обратите внимание, что я ограниченный общий тип T
по признаку Shape
(что вы должны создать). Вы можете поместить любые границы, которые вам нравятся (или вообще не имеют границ), но вы будете ограничены использованием этих признаков.
Все, что вы хотите иметь доступ к своим фигурам, должно быть выставлено Shape
. Например, если вам нужен центр и область, то определение черта может выглядеть следующим образом:
trait Shape {
fn center(&self) -> (f64, f64);
fn area(&self) -> f64;
}
Если это не достаточная гибкость, вы могли бы также дать ShapeRenderer
специальное поведение только для определенных форм. Например:
impl ShapeRenderer<Rectangle> {
fn n_sides(&self) -> u32 {
4
}
}
Обратите внимание, что в этом impl
, мы имеем доступ к всем областям Rectangle
, а не только функции в Shape
.
В качестве альтернативы, вы можете создать базу-структуру, а затем включить его в качестве члена вашей конечных структур:
struct Renderer {
canvas: Canvas,
origin: Point,
}
struct CircleRenderer {
renderer: Renderer,
shape: Circle,
}
struct RectangleRenderer {
renderer: Renderer,
shape: Rectangle,
}
Это самая близкая вещь в Русте к стандартному наследству.
В-третьих, если вы заботитесь только о дублировании кода при создании этих структур и не хочу им делиться ничего, кроме полей, вы можете использовать макрос:
macro_rules! make_renderer {
($name: ty, $shape: ty) => (
struct $name {
canvas: Canvas,
origin: Point,
shape: $shape,
}
);
}
make_renderer!(CircleRenderer, Circle);
make_renderer!(RectangleRenderer, Rectangle);
В то время как пример обобщений является самым сложным, он также является самым мощным и гибким. Это позволяет вам легко распределять код между вашими структурами, а также позволять вам иметь код, специфичный для одного, который дает вам доступ ко всем его полям.
Я нашел аналогичный вопрос, где ответ рассказывает о композиции -> http://stackoverflow.com/questions/32736170/what-is-the-best-way-to-inherit-a-struct-in-ust- 1-3. – xetra11
В качестве альтернативы мы могли бы использовать 'struct Renderer'. –
kennytm
@kennytm Я бы не сказал, что это «альтернатива» - это * * состав! – Shepmaster