Given a struct with a generic Option<T> where T might not implement Clone why can't None be cloned? Isn't a None of type T the same as any other None? For example:
struct Foo<T> {
bar: Vec<Option<T>>,
}
impl <T> Foo<T> {
fn blank(size: usize) -> Foo<T> {
Foo {
bar: vec![None; size],
}
}
}
The derive d implementation of Clone calls clone on each field. For a generic struct, #[derive] implements Clone conditionally by adding bound Clone on generic parameters.
Trait std::clone::Clone1.0. A common trait for the ability to explicitly duplicate an object. Differs from Copy in that Copy is implicit and extremely inexpensive, while Clone is always explicit and may or may not be expensive.
As the other answers correctly point ouf, this is due to the way the vec!-macro is implemented. You can manually create a Vec of any Option<T> without requiring T to be Clone:
let bar = std::iter::repeat_with(|| Option::<T>::None).take(size).collect::<Vec<_>>();
This will create size-number of Option::<T>::None and place them in a Vec, which will be pre-allocated to the appropriate size. This works for any T.
Isn't a
Noneof typeTthe same as any otherNone?
Definitely not! Unlike reference-based languages where null is typically implemented as a null-reference, Rust's Option<T> introduces no indirection and stores T inline when the option is Some. Since all enum variants have the same size, the None variant must still occupy at least as much space as T.
Having said that, it is technically true that the None value could be cloned without T being Clone simply because the None variant of the enum doesn't contain the T, it only stores the discriminator and reserves space that could contain T if the variant were to change to Some. But since Rust enum variants are not separate types, a trait bound defined for the enum must cover all variants.
See other answers more detailed explanations and instructions how to create a vector of None values of a non-cloneable Option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With