oop - 在Rust中设计UI元素树结构

标签 oop design-patterns rust

由于在Rust中缺乏继承,我偶然发现了一个有点古怪的情况。

我正在设计一个元素结构,其中所有元素都有某些共同的行为(例如,有 child )并且需要在树上传播函数调用。

我当前的设计是具有View特性和一个封装所有常见行为的ViewInner结构。但是,这样做似乎会产生大量的样板代码,从而将调用从View转发到其ViewInner。并且看起来,添加另一级别的封装(例如AutoLayoutView)将使调用深度增加三倍。

这是一个简短的示例:

// "Base" view trait
pub trait View {
    fn render(&self, ...);
    fn handle_events(&self, ...);
}

// View internals
pub struct ViewInner {
    children: Vec<Box<View>>
}

impl ViewInner {
    ...
    pub fn add_child(...);
    pub fn layout(...);
}

// Forwarded calls
impl View for ViewInner {
    fn render(&self, ...) {
        for child in self.children.iter() {
            child.render(...);
        }
    }

    fn handle_events(&self, ...) {
        for child in self.children.iter() {
            child.handle_events(...);
        }
    }
}

// Actual entity
pub struct SomeView {
    inner: ViewInner,
    ...
}

impl SomeView {
    pub fn new() -> Self {
        return Self {
            inner: ViewInner::new()
        }
    }
}

impl View for SomeView {
    // Forwarding all over again
    fn render(&self, ...) {
        self.inner.render(...)
    }
    fn handle_events(&self, ...) {
        self.inner.handle_events(...)
    }
}

在将来(在更多的爬网调用和View变体的情况下),构造此结构并最小化样板的最佳方法是什么?

最佳答案

对于在没有任何附加逻辑的情况下转接调用的一般情况,您可以为View特性编写custom derive macro
有了它,您只需要编写:

#[derive(View)]
pub struct ViewInner {
    ...
}

并且View特性会自动为该结构实现。

关于oop - 在Rust中设计UI元素树结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61718187/

相关文章:

php - 为什么无法使用神奇的 __set() 方法直接访问数组?

java - 根据字符串标识符检查对象字段

c# - 如果要处理 SqlDataReader,是否需要调用 close()?

sql - 同步客户端-服务器数据库

php - 清洁架构中的记录器

rust - 如何在 Rust 中使用自由类型绑定(bind)?

Rust 结构中的生命周期范围

java - 当组合需要访问封闭类时进行建模?

javascript - 如何在没有方法的情况下将对象属性 'talk' 相互转换?

rust - 如何对向量的子集进行操作?