创建一个不能在其箱子外实例化的零大小结构的惯用方法是什么?

What is an idiomatic way to create a zero-sized struct that can't be instantiated outside its crate?

我有类似的东西:

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;
}

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

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

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

pub struct A {
    empty: (),
}

或者这样:

pub struct A(());

但是,我不确定哪种方式最地道。

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

pub struct A(());

由于该字段是私有的,因此该模块之外的任何人都不能构造 A

这是用的inside the standard library:

pub struct Stdin(());
pub struct Stdout(());
pub struct Stderr(());

标准库also uses the named field version:

pub struct Empty {
    _priv: (),
}

您可以使用任何 zero-sized 类型(例如 zero-length 数组或 PhantomData),但 () 是最简单的。

另请参阅: