I have a Vec
containing boxed trait objects which I'd like to extend
by the result of an iterator. Performing an loop-and-push approach works fine but using the extend
-method fails with:
error[E0271]: type mismatch resolving `<std::iter::Map<std::ops::Range<usize>, [closure@src/main.rs:7:47: 7:72]> as std::iter::IntoIterator>::Item == std::boxed::Box<dyn MyTrait>`
--> src/main.rs:13:9
|
13 | vec.extend(new_elements);
| ^^^^^^ expected struct `MyStruct`, found trait MyTrait
|
= note: expected type `std::boxed::Box<MyStruct>`
found type `std::boxed::Box<dyn MyTrait>`
This is my code: Rust Playground
struct MyStruct {}
trait MyTrait {}
impl MyTrait for MyStruct {}
fn main() {
let mut vec: Vec<Box<MyTrait>> = vec![];
let mut new_elements = (0..16_usize).map( |_| Box::new(MyStruct {}));
// works
vec.push(new_elements.next().unwrap());
// doesn't work
vec.extend(new_elements);
// works (std implementation of Vec::extend)
while let Some(element) = new_elements.next() {
let len = vec.len();
if len == vec.capacity() {
let (lower, _) = new_elements.size_hint();
vec.reserve(lower.saturating_add(1));
}
unsafe {
std::ptr::write(vec.get_unchecked_mut(len), element);
// NB can't overflow since we would have had to alloc the address space
vec.set_len(len + 1);
}
}
}
I find the error message confusing - I expected the expected and found types to be swapped.
Do I have to provide some type hints? Can I add a map
to cast the type into a trait object?