I found four different ways to create a struct
with no data:
struct A{} // empty struct / empty braced struct
struct B(); // empty tuple struct
struct C(()); // unit-valued tuple struct
struct D; // unit struct
(I'm leaving arbitrarily nested tuples that contain only ()
s and single-variant enum
declarations out of the question, as I understand why those shouldn't be used).
What are the differences between these four declarations? Would I use them for specific purposes, or are they interchangeable?
The book and the reference were surprisingly unhelpful. I did find this accepted RFC (clarified_adt_kinds) which goes into the differences a bit, namely that the unit struct also declares a constant value D
and that the tuple structs also declare constructors B()
and C(_: ())
. However it doesn't offer a design guideline on why to use which.
My guess would be that when I export them with pub
, there are differences in which kinds can actually be constructed outside of my module, but I found no conclusive documentation about that.
D
the most obvious choice) – Flatheadstruct A { _marker: PhantomData }
is also a zero-sized struct,struct A<T> { t: T }
is a zero-sized struct ifT
is zero-sized,enum A {}
(a no-variantenum
) is also zero-sized, ... – DenudationPhantomData
has a clear purpose, I know when to use that. A no-variant enum is like!
(void) not()
(unit), no value can exist at all. – Flatheadstruct E();
thanstruct E;
? That would make more sense. – Kellestruct E;
a "unit-like struct". – Flathead