下面是我的代码中的一个简化示例,它读取目录,遍历文件,并在每个文件的末尾附加注释......
此示例显示Vec<Option<bool>>
,在调用iter()
后,编译器将Option<_>
解释为借用&Option<_>
类型。我想明白为什么我会看到这种行为。
fn main() {
let vec = vec![Some(true), None];
vec.iter()
.filter_map(|o| o)
.count();
}
编译器输出
src/main.rs:50:25: 50:26 error: mismatched types:
expected `core::option::Option<_>`,
found `&core::option::Option<bool>`
(expected enum `core::option::Option`,
found &-ptr) [E0308]
src/main.rs:50 .filter_map(|o| o)
答案 0 :(得分:4)
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
}
换句话说,每次调用Iterator::next
时返回的值的类型将是对向量中项目的引用。
如果您更改为vec.into_iter()
,则代码可以正常运行:
fn main() {
let vec = vec![Some(true), None];
vec.into_iter()
.filter_map(|o| o)
.count();
}
在这种情况下,您正在迭代IntoIter
结构,以不同方式实现Iterator
,返回对象本身:
impl<T> Iterator for IntoIter<T> {
type Item = T;
}
这是必需的,因为一次只能有一件东西拥有每个矢量项。通常,您希望让向量拥有该项并对引用进行操作。 into_iter
使用向量,将整个向量的所有权转移到IntoIter
结构。然后允许该结构将每个项目的所有权赋予filter_map
调用。
如果您的类型实现了Clone
,您还可以克隆每个项目。这允许向量保持所有权并创建一个新项目:
fn main() {
let vec = vec![Some(true), None];
vec.iter()
.cloned()
.filter_map(|o| o)
.count();
}
答案 1 :(得分:1)
这个怎么样:
fn main() {
let my_vec = vec![Some(true), None];
println!("{}", my_vec.iter().filter_map(|&x| x).count());
}
应用filter_map
后,您可以将&x
映射到x
,您的代码就可以使用。
正如@Shepmaster在评论中指出的那样,这只适用于实现Copy
的类型。