Enum variants do not have their own type. There is only the type of the enum itself. Check out this example:
enum Thing<T> {
One,
Two(T),
}
fn main() {
let a = Thing::One;
let b = Thing::Two(true);
}
The type of b
is a Thing<bool>
. The type has no mention of Two
. The same thing needs to happen for a
, but there's nothing that the compiler can use to infer the value of T
, so you have to provide it explicitly:
let a = Thing::One::<u8>;
And an even-smaller example is to use an enum that is built-in and very familiar — Option
:
fn main() {
// let a = None;
let a = None::<u8>;
let b = Some(true);
}
I don't need the type T so it seems pointless to do so.
Let's dive in a bit deeper. An enum takes up the space of the max of all the variants (plus a wee bit to tell them apart):
enum Foo {
One(u64),
Two(u8),
}
fn main() {
println!("{}", std::mem::size_of::<u64>());
// 8
println!("{}", std::mem::size_of::<u8>());
// 1
println!("{}", std::mem::size_of::<Foo>());
// 16
}
Also, all variants of the same enum take up the same amount of space:
fn main() {
let a = Some(true);
let b = None::<bool>;
println!("{}", std::mem::size_of_val(&a));
// 2
println!("{}", std::mem::size_of_val(&b));
// 2
}
This helps lead us to the realization that not all None
s are the same:
fn main() {
let a = None::<u8>;
println!("{}", std::mem::size_of_val(&a));
// 2
let b = None::<u64>;
println!("{}", std::mem::size_of_val(&b));
// 16
}
Thus it is important to know exactly what kind of None
you have. This extends to every kind of enum and variant.
T
? – ShepmasterT
, but it seems to be buggy with inference: This doesn't work, but this does. – oli_obk