I found four different ways to create a struct
with no data:
struct A{} // empty struct / empty braced struct
<
There are only two functional differences between these four definitions (and a fifth possibility I'll mention in a minute):
pub
, whether its constructor (also called struct literal syntax) is usable outside the module it's defined in.The only one of your examples that is not directly constructible from outside the current module is C
. If you try to do this, you will get an error:
mod stuff {
pub struct C(());
}
let _c = stuff::C(()); // error[E0603]: tuple struct `C` is private
This happens because the field is not marked pub
; if you declare C
as pub struct C(pub ())
, the error goes away.
There's another possibility you didn't mention that gives a marginally more descriptive error message: a normal struct, with a zero-sized non-pub
member.
mod stuff {
pub struct E {
_dummy: (),
}
}
let _e = stuff::E { _dummy: () }; // error[E0451]: field `_dummy` of struct `main::stuff::E` is private
(Again, you can make the _dummy
field available outside of the module by declaring it with pub
.)
Since E
's constructor is only usable inside the stuff
module, stuff
has exclusive control over when and how values of E
are created. Many structs in the standard library take advantage of this, like Box
(to take an obvious example). Zero-sized types work in exactly the same way; in fact, from outside the module it's defined in, the only way you would know that an opaque type is zero-sized is by calling mem::size_of.