gpt4 book ai didi

rust - 创建为 IntoIterator 复制的方法

转载 作者:行者123 更新时间:2023-12-03 11:43:53 24 4
gpt4 key购买 nike

首先,我想要一个接受泛型集合但不消耗它的函数。也就是说,我们有一个函数 non_consuming .

fn non_consuming<'a,I>(_: &'a I)
where &'a I: std::iter::IntoIterator<Item = usize> {}
由于特定原因,我无法更改 Item要求 &usize .如果我想像这样正常使用此方法,则编译器会抛出错误:
non_consuming(&vec![0usize,1,2]);
因为 IntoIterator&Vec 实现,但与 Item = &T .这样我就有了实现类似 copied 的想法。但对于 IntoIterator而不是 Iterator .
我的目标是创建一个方法 into_copied对于任何 IntoIteratorItem: &T它返回一个结构 C实现 IntoIteratorItem: T &C还应该实现 IntoIteratorItem: T .
我使用扩展特性来实现 into_copied对于任何 IntoIterator其余代码强烈关注如何 copied已实现:
pub struct IntoIterCopied<I>
{
into_iter: I,
}

impl<I> IntoIterCopied<I>
{
pub fn new(iter: I) -> Self {
IntoIterCopied{
into_iter: iter,
}
}
}

impl<'a,I,T> IntoIterator for IntoIterCopied<I>
where
I: IntoIterator<Item = &'a T>,
T: 'a + Copy
{
type Item = T;
type IntoIter = std::iter::Copied<I::IntoIter>;
fn into_iter(self) -> Self::IntoIter {
self.into_iter.into_iter().copied()
}
}

pub trait IntoIterCopiedExt {
fn into_copied<'a, T>(self) -> IntoIterCopied<Self>
where
Self: Sized + IntoIterator<Item = &'a T>,
T: 'a + Copy
{
IntoIterCopied::new(self)
}
}

impl<T> IntoIterCopiedExt for T
where T: IntoIterator {}
我想我现在可以使用函数 non_consuming像这样:
let into_iter_adap = (&vec![0usize,1,2]).into_copied();
non_consuming(&into_iter_adap);
然而,这是我得到的错误:
error[E0277]: `&IntoIterCopied<&Vec<usize>>` is not an iterator
--> src/main.rs:46:19
|
40 | fn non_consuming<'a,I>(_: &'a I)
| ------------- required by a bound in this
41 | where &'a I: std::iter::IntoIterator<Item = usize>
| ------------------------------------- required by this bound in `non_consuming`
...
46 | non_consuming(&into_iter_adap);
| ^^^^^^^^^^^^^^^ `&IntoIterCopied<&Vec<usize>>` is not an iterator
|
= help: the trait `Iterator` is not implemented for `&IntoIterCopied<&Vec<usize>>`
= note: required because of the requirements on the impl of `IntoIterator` for `&IntoIterCopied<&Vec<usize>>`
我不确定错误告诉我什么。我实现了 IntoIteratorIntoIterCopied但不适用于 &IntoIterCopied ,那么为什么笔记告诉我它将被实现?
Rust Playground

最佳答案

这里有很多噪音分散了我想象的目标。让我们一次做一件事。
放松签名non_consumingnon_consuming有一个不必要的限制函数签名:它要求它的参数是形式 &I ,当它实际需要的是参数是 IntoIterator<Item = usize> .这意味着即使您有 Vec<usize>要通过(您不会,但请耐心等待),您无法将其传递给 non_consuming ;您将被迫将其保留在调用方中。决定是否消费,不需要的时候,应该是调用者的问题;这个功能不应该关心。我们可以在不失一般性的情况下重写它:

fn maybe_consuming<II>(_: II)
where
II: std::iter::IntoIterator<Item = usize>,
{
}
maybe_consuming仍将接受任何引用 non_consuming会,因为 II可以作为引用。
替换 IntoIterCopied您不需要包装 IntoIterator在一个结构中给它一个 into_copied方法。 (如果您希望 &a_vec 总是产生 usize s,您可以考虑包装 a_vec ,但在这种情况下似乎没有必要。)您可以制作一个提供 into_copied 的扩展特征并返回 Copied<Self::IntoIter>直接地。
pub trait IntoCopied {
fn into_copied<'a, T>(self) -> std::iter::Copied<Self::IntoIter>
where
Self: Sized + IntoIterator<Item = &'a T>,
T: 'a + Copy,
{
self.into_iter().copied()
}
}

impl<I> IntoCopied for I where I: IntoIterator {}
因为 Copied<I>Iterator因此实现 IntoIterator ,任何适用于原始版本的代码都应该仍然适用于这个版本。
修复调用者
maybe_consuming已更改为允许非引用,我们可以通过 .into_copied()直接给它:
fn main() {
let vec_ref = &vec![0usize, 1, 2];
maybe_consuming(vec_ref.into_copied());
}

关于rust - 创建为 IntoIterator 复制的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66259256/

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