[英]Value of type `Vec<&str>` cannot be built from `std::iter::Iterator<Item=&&str>`
Why does this code work properly为什么这段代码可以正常工作
fn main() {
let v1 = vec!["lemonade", "lemon", "type", "lid"];
println!("{:?}", v1.iter().filter(|item| item.starts_with("l")).collect::<Vec<_>>());
}
While this code gets me an error, I kinda get the sense why this isn't working and I get how to fix it, but I don't really understand what type is it returning so I can replace the "_" to something not that generic虽然这段代码给我一个错误,但我有点明白为什么这不起作用并且我知道如何修复它,但我真的不明白它返回的是什么类型,所以我可以将“_”替换为不那个通用的
fn main() {
let v1 = vec!["lemonade", "lemon", "type", "lid"];
println!("{:?}", v1.iter().filter(|item| item.starts_with("l")).collect::<Vec<&str>>());
}
The error错误
error[E0277]: a value of type `Vec<&str>` cannot be built from an iterator over elements of
type `&&str`
--> src\main.rs:3:69
|
3 | println!("{:?}", v1.iter().filter(|item| item.starts_with("l")).collect::
<Vec<&str>>());
| ^^^^^^^ value of type
`Vec<&str>` cannot be built from `std::iter::Iterator<Item=&&str>`
|
= help: the trait `FromIterator<&&str>` is not implemented for `Vec<&str>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
note: required by a bound in `collect`
--> C:\Users\Mululi\.rustup\toolchains\stable-x86_64-pc-windows-
msvc\lib/rustlib/src/rust\library\core\src\iter\traits\iterator.rs:1788:19
|
1788 | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
I couldn't fully understand what the compiler meant by that我无法完全理解编译器的意思
Let's look at the types in detail.让我们详细看看这些类型。 It will take a couple of documentation derefs to get to the bottom so bear with me.
这将需要几个文档 derefs 才能深入了解,所以请耐心等待。
let v1 = vec,["lemonade", "lemon", "type"; "lid"];
v1
is a Vec<&str>
. v1
是一个Vec<&str>
。
v1.iter()
Vec
doesn't have an iter
method, but it implements Deref<Target = [T]>
which does : Vec
没有iter
方法,但 它实现Deref<Target = [T]>
:
pub fn iter(&self) -> Iter<'_, T>
Iter
here is a struct named std::slice::Iter
. Iter
这里是一个名为std::slice::Iter
的结构。 What kind of iterator is it?它是什么样的迭代器? We need to take a look at its
Iterator
implementation :我们需要看看它的
Iterator
实现:
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
}
This tells us that the iterator yields item of type &T
.这告诉我们迭代器产生
&T
类型的项目。 Remember that we have a Vec<&str>
, so T = &str
.请记住,我们有一个
Vec<&str>
,所以T = &str
。 That means that what we really have is an Iterator<Item = &&str>
.这意味着我们真正拥有的是一个
Iterator<Item = &&str>
。 That's the source of the error you're getting.这就是你得到的错误的根源。
So, how do we get an Iterator<Item = &str>
instead of a Iterator<Item = &&str>
?那么,我们如何获得
Iterator<Item = &str>
而不是Iterator<Item = &&str>
呢? There are several ways, including:有几种方法,包括:
into_iterator()
into_iterator()
Use Vec
's implementation of IntoIterator
which has Item = T
.使用
Vec
的IntoIterator
实现,它具有Item = T
。 into_iterator()
yields T
s instead of &T
s. into_iterator()
产生T
s 而不是&T
s。
v1.into_iter().filter(...)
This is efficient, but note that it consumes the vector.这是有效的,但请注意它消耗了向量。 It doesn't return an iterator that references the items, it actually moves the items out of the vector and into the consuming code.
它不返回引用项目的迭代器,它实际上将项目移出向量并进入消费代码。 The vector is unuseable after calling
into_iter
.调用
into_iter
后,该向量无法使用。
iter().copied()
iter().copied()
If T: Copy
you can call copied
to turn an Iterator<Item = &T>
into an Iterator<Item = T>
. If
T: Copy
你可以调用copied
来把一个Iterator<Item = &T>
变成一个Iterator<Item = T>
。
v1.iter().copied().filter(...)
This technique is great because it doesn't consume the vector, and it will work because &str
is indeed Copy
.这种技术很棒,因为它不消耗向量,而且它会起作用,因为
&str
确实是Copy
。 All references are Copy
thanks to this blanket implementation :由于此一揽子实施,所有参考资料都是
Copy
:
impl<T: ?Sized> Copy for &T {}
iter().cloned()
iter().cloned()
If T: Clone
you can call cloned
to clone all the items and turn an Iterator<Item = &T>
into an Iterator<Item = T>
.如果
T: Clone
您可以调用cloned
来克隆所有项目并将Iterator<Item = &T>
转换为Iterator<Item = T>
。
v1.iter().cloned().filter(...)
Anything that's Copy
is also Clone
, so you could indeed clone the &str
references.任何
Copy
也是Clone
,因此您确实可以克隆&str
引用。
You need to collect into Vec<&&str>
, not Vec<&str>
.您需要收集到
Vec<&&str>
,而不是Vec<&str>
。 The original vector is Vec<&str>
, and iter()
produces an iterator over references to the elements, so the iterator yields &&str
s.原始向量是
Vec<&str>
,并且iter()
在对元素的引用上产生一个迭代器,因此迭代器产生&&str
s。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.