问题
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