EN VI

Rust - let foo: Vec<Option<T>> = vec![None; 10]; without T implementing Clone?

2024-03-12 19:30:05
How to Rust - let foo: Vec> = vec![None; 10]; without T implementing Clone

I want to fill a Vector of "Option" with "None" values. This is done with this code

let mut foo: Vec<Option<T>> = Vec::with_capacity(capacity);
for _ in 0..capacity {
    foo.push(None);
}

but actually I really would like to have this shorter like

let foo: Vec<Option<T>> = vec![None; capacity];

Unfortunately, my generic T is not clonable and therefore the expression cannot apply None. Is there a way to tell the expression that None is clonable?

Solution:

In Rust a trait can only be implemented for a type, not for individual variants of an enum, so unfortunately, Option::<T>::None may not be Clone if T is not.

Possible workarounds:

  • Your original solution, albeit not a one-liner.
  • Vec::from_iter((0..capacity).map(|_| None)), as suggested by @cafce25.
  • std::iter::repeat_with(|| None).take(capacity).collect::<Vec<_>>(), as suggested by @vallentin.
  • You can also use Vec::resize_with, since Option<T> will be Default, no matter the T:
    let mut foo: Vec<Option<T>> = Vec::with_capacity(capacity);
    vec.resize_with(5, Default::default);
    
  • You can declare a macro similar to vec! that will expand to one of the above, if you need to use such a declaration many times and want to de-noise the code a bit. However, it's probably best to not do this if you only need to create such a Vec a small number of times.
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login