什么是创建无法在其板条箱外实例化的零大小结构的惯用方法?

ano*_*ose 6 idioms rust

我有类似的东西:

mod private {
    // My crate
    pub struct A;
    
    impl A {
        pub fn new() -> Self {
            Self
        }
        // ...
    }
}

fn main() {
    // External code
    let obj = private::A::new();
    let obj2 = private::A;
}
Run Code Online (Sandbox Code Playgroud)

目前,A不需要存储任何内部状态来执行我想要的操作(它只是在枚举中用作占位符),因此我将其设为零大小的结构。然而,这在未来可能会改变,所以我想防止这个板条箱外的代码在A没有通过A::new()的情况下实例化(即obj2in的实例化main()应该失败)。

从本质上讲,我想要的效果就像我向 中添加了一个私有字段一样A,但我希望它保持零大小。

目前,我正在考虑这样的事情:

pub struct A {
    empty: (),
}
Run Code Online (Sandbox Code Playgroud)

或这个:

pub struct A(());
Run Code Online (Sandbox Code Playgroud)

但是,我不确定哪种方式最惯用。

She*_*ter 8

对此没有既定的习语。我会使用元组结构版本:

pub struct A(());
Run Code Online (Sandbox Code Playgroud)

由于该字段是私有的,该模块之外的任何人都无法构造A.

在标准库中使用

pub struct Stdin(());
pub struct Stdout(());
pub struct Stderr(());
Run Code Online (Sandbox Code Playgroud)

标准库使用命名字段 version

pub struct Empty {
    _priv: (),
}
Run Code Online (Sandbox Code Playgroud)

您可以使用任何大小为零的类型(例如零长度数组或PhantomData),但这()是最简单的。

也可以看看: