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

我是研究僧i 提交于 2020-12-08 07:23:40

问题


I have something similar to this:

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

Currently, A doesn't need to store any internal state to do what I want it to (it's just being used as a placeholder in an enum), so I made it a zero-sized struct. However, that might change in the future, so I want to prevent code outside this crate from instantiating A without going through A::new() (i.e. the instantiation of obj2 in main() as it stands should fail).

Essentially, I want the same effect as if I'd added a private field to A, but I want it to remain zero-sized.

Currently, I'm thinking about something like this:

pub struct A {
    empty: (),
}

Or this:

pub struct A(());

However, I'm not sure which way is most idiomatic.


回答1:


There is no established idiom for this. I'd use the tuple struct version:

pub struct A(());

Since the field is private, no one outside that module can construct A.

This is used inside the standard library:

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

The standard library also uses the named field version:

pub struct Empty {
    _priv: (),
}

You could use any zero-sized type (e.g. a zero-length array or PhantomData), but () is the simplest.

See also:

  • Why define a struct with single private field of unit type?
  • What's the Rust idiom to define a field pointing to a C opaque pointer?
  • What are the differences between the multiple ways to create zero-sized structs?


来源:https://stackoverflow.com/questions/64651511/what-is-an-idiomatic-way-to-create-a-zero-sized-struct-that-cant-be-instantiate

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!