An Option
can only be cloned if the inner T
implements Clone
:
impl<T> Clone for Option<T>
where
T: Clone,
Isn't a None
of type T
the same as any other None
?
Actually, no. The Rust compiler does not even view None
as a type. Instead, None
is just a variant (subtype) of Option<T>
. Try comparing None
s of two different T
s:
let a: Option<String> = None;
let b: Option<u8> = None;
assert_eq!(a, b)
You will see that they are in fact completely unrelated types:
error[E0308]: mismatched types
--> src/main.rs:4:5
|
4 | assert_eq!(a, b)
| ^^^^^^^^^^^^^^^^ expected struct `String`, found `u8`
|
= note: expected enum `Option<String>`
found enum `Option<u8>`
So the Rust compiler actually sees None
as Option::<T>::None
. This means that if T
is not Clone
, then Option<T>
is not Clone
, and therefore Option::<T>::None
cannot be Clone
.
To make your code compile, you must constrain T
to Clone
:
struct Foo<T: Clone> {
bar: Vec<Option<T>>,
}
impl <T: Clone> Foo<T> {
fn blank(size: usize) -> Foo<T> {
Foo {
bar: vec![None; size],
}
}
}
Now the compiler knows that T
is Clone
, and the implementation of Clone
for Option<T>
(and Option::<T>::None
) is fulfilled.
None
of typeT
the same as any otherNone
?" - no,None
is a variant ofOption<T>
. Its full name would beOption::<T>::None
, but you often don't need that since the type is usually inferred. – Launalaunce