如何声明只有一些成员可以使用另一个结构中的值的结构?

时间:2016-12-12 04:40:50

标签: struct rust default-value

Rust有一个很有用的功能,您可以使用现有的结构,只覆盖其中的一些成员。例如,以下结构的值

struct SomeTool {
    pub unique_id: String,
    pub poll: Option<fn(&Context) -> bool>,
    pub exec: Option<fn(&mut Context) -> ToolResult>,
    pub modal: Option<fn(&mut Context) -> ToolResult>,
    pub ui: Option<fn(&mut UIPanel)>,
}

可以通过传入结构实例(例如SomeTool::default())来初始化:

new_tool = SomeTool {
    unique_id: "tool.foobar".to_string(),
    exec: Some(foobar_exec)
    .. SomeTool::default()
};

我希望能够在不必明确列出每个回调的情况下声明SomeTool(将来添加新的回调可能会导致在代码库中添加None次。)

这很好用,但现在我可能会意外地遗漏unique_id进行其他一些初始化,它会使用default中的任何内容。

有没有办法描述一个结构可以让某些成员被覆盖而不是其他成员?

请注意,现实世界的用例拥有的成员多于此数(使事故发生率更高),只是简化了问题。

1 个答案:

答案 0 :(得分:8)

由于unique_id应该是唯一的,因此它不应该有Default构造函数。但是,如果您从假设的Default类型中移除UniqueId impl,那么您将无法为Default派生SomeTool

目前正在使用的解决方案是将所有不需要值的字段移到子结构中,而不是为Default实现SomeTool。因此,您可以按如下方式使用SomeTool

new_tool = SomeTool {
    unique_id: "tool.foobar".to_string(),
    callbacks: Callbacks {
        exec: Some(foobar_exec),
        .. Callbacks::default()
    }
};

Rust可能会在将来获得一个假设的特性,它允许您将两个具有相同字段的结构作为结构表达式中的基本表达式。该功能允许您使用子结构来初始化子结构和SomeTool共有的所有字段,但不能更多。