gpt4 book ai didi

rust - 类型 `Vec<&str>` 的值不能从 `std::iter::Iterator` 构建

转载 作者:行者123 更新时间:2023-12-05 01:50:05 24 4
gpt4 key购买 nike

为什么这段代码可以正常工作

fn main() {
let v1 = vec!["lemonade", "lemon", "type", "lid"];
println!("{:?}", v1.iter().filter(|item| item.starts_with("l")).collect::<Vec<_>>());
}

虽然这段代码给我一个错误,但我有点明白为什么它不起作用,我知道如何修复它,但我不太明白它返回的是什么类型,所以我可以替换“_”一些不那么通用的东西

fn main() {
let v1 = vec!["lemonade", "lemon", "type", "lid"];
println!("{:?}", v1.iter().filter(|item| item.starts_with("l")).collect::<Vec<&str>>());
}

错误

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`

我无法完全理解编译器的意思

最佳答案

解释错误

让我们详细看一下类型。这将需要几个文档 derefs 才能到达底部,所以请耐心等待。

let v1 = vec!["lemonade", "lemon", "type", "lid"];

v1Vec<&str> .

v1.iter()

Vec没有 iter方法,但它实现了 Deref<Target = [T]> which does :

pub fn iter(&self) -> Iter<'_, T>

Iter这是一个名为 std::slice::Iter 的结构.它是什么样的迭代器?我们需要看看它的 Iterator implementation :

impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
}

这告诉我们迭代器产生类型为 &T 的项目.请记住,我们有一个 Vec<&str> , 所以 T = &str .这意味着我们真正拥有的是一个 Iterator<Item = &&str> .这就是您遇到的错误的来源。

修复

那么,我们如何获得 Iterator<Item = &str>而不是 Iterator<Item = &&str> ?有几种方法,包括:

1。 into_iterator()

使用 Vecimplementation of IntoIterator 其中有 Item = T . into_iterator()产量 T s 而不是 &T

v1.into_iter().filter(...)

这是高效的,但请注意它会消耗向量。它不会返回引用项目的迭代器,它实际上将项目移出向量并移入使用代码。调用 into_iter 后向量无法使用.

2。 iter().copied()

如果T: Copy你可以调用 copied 转动 Iterator<Item = &T>进入 Iterator<Item = T> .

v1.iter().copied().filter(...)

这项技术很棒,因为它不消耗向量,而且它会起作用,因为 &str确实是Copy .所有引用资料均为 Copy感谢这个blanket implementation :

impl<T: ?Sized> Copy for &T {}

3。 iter().cloned()

如果T: Clone你可以调用 cloned 克隆所有项目并打开 Iterator<Item = &T>进入 Iterator<Item = T> .

v1.iter().cloned().filter(...)

任何Copy也是Clone , 所以你确实可以克隆 &str引用资料。

关于rust - 类型 `Vec<&str>` 的值不能从 `std::iter::Iterator<Item=&&str>` 构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73439192/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com