Общая настройка: у меня есть массив значений, которые я бы хотел map()
, а затем chain()
с 1 дополнительным значением. Из этого ответа я узнал, что правильный способ построить это окончательное значение - использовать std::iter::once
. Это работает и устранило нижеприведенную проблему, но я все же хотел бы понять ее лучше .
В моем сломанном, вероятно, ржавом-анти-шаблонно-пронизанном примере я использовал массиводин элемент, а затем вызывать into_iter()
. Это привело к несовпадению значений / ссылок в цепочке.
Вопрос: Что такое механизм Rust-idiomatic для исправления этого несоответствия значений / ссылок? Особенно, если clone
и copy
недоступны.
Справочная информация: Почему начинается несоответствие типов для начала?
Я так понимаю, что понимаю. Основываясь на определении std :: iter :: Map , тип элемента для итератора равен type Item = B
, где B
ограничен F: FnMut(<I as Iterator>::Item) -> B
(то есть сопоставленный тип). Однако array определяет следующие 2 IntoIterator
реализации, каждая из которых, по-видимому, создает ссылки.
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
Пример, демонстрирующий проблему:
#[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[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`
Пример детской площадки Rust .