【问题标题】:How to use a struct without initializing its members?如何在不初始化其成员的情况下使用结构?
【发布时间】:2022-10-17 00:35:52
【问题描述】:

我正在尝试使用一个结构而不初始化它的一些成员,以便能够使用它:

struct Structure {
    initialized: bool,
    data: StructureData, // This is another struct...
    target: TargetTrait, // This member that I don't need to initialize.
}

impl Structure {
    pub fn initialize(&mut self) -> bool {
        if self.initialized {
            false
        } else {
            // Here I should initialize the target...
            self.target = initializeTarget(...); // No problem...
            self.initialized = true;
            true
        }
    }

    pub fn new(&self) -> Structure {
        Structure {
            initialized: false,  // The initialize method will do that...
            data: StructureData, // Initializing Structure data behind the
            // scenes...
            // Here the struct needs some value for the target, but I cannot provide any value,
            // Because the initialization method will do that job...
            target: None, // I tried using (None), and Option<T>,.
                          // But the TargetTrait refused.
        }
    }
}

// main function:
fn main() {
    let structure: Structure = Structure::new(); // It should construct a new structure...
    if structure.initialize() {
        // Here, I should do some work with the target...
    }
}

我尝试使用 Option,但目标 trait 没有实现 Option,甚至没有实现

#[derive(Default)]

【问题讨论】:

  • 目标特征是什么意思?如果您受到某个特征的限制,而这正是您提出问题的真正原因,那么也请在您的问题中包含该特征。
  • @Peter Hall,该特征是一个外部库!

标签: rust struct initialization member


【解决方案1】:

这可以使用Typestate 模式以构建器类型的形式解决。

这种模式背后的基本思想是在运行时不应表示无效状态(例如,在这种情况下,通过更改initialized 字段的值)。 相反,这应该由类型系统在编译时处理。

例如,在这里您将使用两种不同的类型。 第一个“未初始化”构建器类型,表示不存在 target 的结构状态,以及包含目标的已初始化 Structure。但是它不包含initialized 字段,因为它是由另一个类构建的,它只能表示一个初始化状态(因此类型状态)。

struct Structure {
    data: StructureData,
    target: TargetTrait,
}

struct StructureBuilder {
    data: StructureData,
}

impl StructureBuilder {
    pub fn initialize(self) -> Structure {
        // Here I should initialize the target...
        Structure {
            data: self.structureData,
            target: initializeTarget(),
        }
    }

    pub fn new() -> StructureBuilder {
        StructureBuilder {
            data: StructureData, // Initializing Structure data behind the scenes
        }
    }
}

此类型负责使用 initialize 方法初始化 target。

但是,方法签名(通过值获取 self)确保 StructureBuilder 的实例以后不能被重用,并且新创建的 Structure 拥有被移动到其中的数据的所有权。

然后它将像这样使用:

fn main() {
    let builder = StructureBuilder::new();
    let structure = builder.initialize();
}

【讨论】:

  • StructureBuilder::new 的定义中有一个额外的 &amp;self 参数
  • @FilipeRodrigues 已修复!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多