The general setup is I have an array of values I'd like to map() and then chain() with 1 additional value. I've learned from this answer that the proper way to construct that final value is to use std::iter::once. This works and eliminated the below problem, but I would still like to understand it better.
In my broken, likely rust-anti-pattern-riddled example, I was using an array of a single element and then calling into_iter(). This produced a value / reference type-mismatch in the chain.
Question: What is the Rust-idiomatic mechanism for correcting this value / reference mismatch? Particularly if clone and copy are unavailable.
Background: Why is there a type mis-match to begin with?
This much I believe I understand. Based on the definition of std::iter::Map, the item type for the iterator is type Item = B where B is constrained by F: FnMut(<I as Iterator>::Item) -> B (i.e. the mapped type). However array defines the following 2 IntoIterator implementations, both of which appear to produce references.
impl<'a, const N: usize, T> IntoIterator for &'a [T; N] where [T; N]: LengthAtMost32, type Item = &'a T impl<'a, const N: usize, T> IntoIterator for &'a mut [T; N] where [T; N]: LengthAtMost32, type Item = &'a mut T Example demonstrating the issue:
#[derive(PartialEq, Eq, Clone, Copy)] enum Enum1 { A, B, C } #[derive(PartialEq, Eq, Clone, Copy)] enum Enum2 { X, Y, Z } struct Data { // Other data omitted e1: Enum1, e2: Enum2 } struct Consumer { // Other data omitted /** Predicate which evaluates if this consumer can consume given Data */ consumes: Box<dyn Fn(&Data) -> bool> } fn main() { // Objective: 3 consumers which consume data with A, B, and X respectively let v: Vec<Consumer> = [Enum1::A, Enum1::B].iter() .map(|&e1| Consumer { consumes: Box::new(move |data| data.e1 == e1) }) // This chain results in an iterator type-mismatch: // expected &Consumer, found Consumer .chain([Consumer { consumes: Box::new(move |data| data.e2 == Enum2::X) }].into_iter()) .collect(); // Fails as well due to the chain failure } Error:
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, Consumer> as std::iter::IntoIterator>::Item == Consumer` --> src/main.rs:52:10 | 52 | .chain([Consumer { consumes: Box::new(move |data| data.e2 == Enum2::X) }].into_iter()) | ^^^^^ expected reference, found struct `Consumer` | = note: expected type `&Consumer` found type `Consumer`