一般的设置是,我有一个想要map()的值数组,然后是一个附加值的chain()。我从这个答案中了解到,构建最终值的正确方法是使用std::iter::once。这样做,并消除了以下问题,但我仍然希望更好地理解它的。
在我破碎的、可能是防锈的例子中,我使用了一个单一元素数组,然后调用了into_iter()。这在链中产生了值/引用类型不匹配。
问题:,纠正这个值/引用错配的锈蚀惯用机制是什么?特别是如果clone和copy不可用的话。
背景:为什么一开始就有一种类型的错误匹配?
我相信我能理解。基于std::iter::Map的定义,迭代器的项类型为type Item = B,其中B受F: FnMut(<I as Iterator>::Item) -> B (即映射类型)的约束。然而,数组定义了以下两个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`发布于 2019-10-13 09:38:31
关于这一点有一个长期存在的问题。技术细节有点重,但从本质上讲,由于底层的技术原因,如果没有大量的hocus,就不能拥有固定大小的数组并返回拥有的引用。当您考虑到什么是固定大小的数组,它是如何存储在内存中,以及如何在不克隆元素的情况下获取元素时,这一点就变得显而易见了。
因此,由于您已经找到了实现,所以只能获得借用的引用。可以使用arrayvec绕过这一问题(因为它们有一个具有自己类型的IntoIterator for ArrayVec的良好实现),或者您可以要求您的所有T: Clone并以这样的方式处理它,而代价是内存中的额外项(临时的;编译器90%的优化时间)。
https://stackoverflow.com/questions/58360894
复制相似问题