Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

idioms

rust

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.

like image 436
anonymoose Avatar asked Nov 02 '20 18:11

anonymoose


People also ask

Why can’t we use + in C structure?

The C structure does not allow the struct data type to be treated like built-in data types: We cannot use operators like +,- etc. on Structure variables. For example, consider the following code: No Data Hiding: C Structures do not permit data hiding. Structure members can be accessed by any function, anywhere in the scope of the Structure.

What is the practical use of empty structs?

While this article concentrated on language obscura, there is one important practical use of empty structs, and that is the chan struct {} construct used for signaling between go routines I’ve talked about the use of chan struct {} in my Curious Channels article.

How do you initialize a point in a struct?

Structure members can be initialized using curly braces ‘ {}’. For example, following is a valid initialization. struct Point. {. int x, y; }; int main () {. struct Point p1 = {0, 1};

Which keyword is used to create a structure?

‘struct’ keyword is used to create a structure. Following is an example. How to declare structure variables? A structure variable can either be declared with structure declaration or as a separate declaration like basic types. Note: In C++, the struct keyword is optional before in declaration of a variable. In C, it is mandatory.


1 Answers

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?
like image 92
Shepmaster Avatar answered Oct 18 '22 04:10

Shepmaster