首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回来自特征函数的复制值的迭代器

返回来自特征函数的复制值的迭代器
EN

Stack Overflow用户
提问于 2021-07-12 18:21:27
回答 1查看 38关注 0票数 1

我要求特征有一个函数,该函数返回某个值类型的迭代器。实现此特征的结构可以简单地存储我们想要迭代的值的(只读)集合。

我尝试了下面的一个人为的例子:

代码语言:javascript
复制
use std::iter::Copied;
use std::collections::{hash_set, HashSet};

trait MyTrait<I: IntoIterator<Item = usize>> {
    fn iter(&self) -> I;
}

struct MyStruct{
    set: HashSet<usize>,
}

type Iter<'a> = Copied<hash_set::Iter<'a, usize>>;

impl MyTrait<Iter<'_>> for MyStruct {
    fn iter(&self) -> Iter<'_> {
        self.set.iter().copied()
    }
}

但是,上面的代码会产生以下编译器错误:

代码语言:javascript
复制
error: `impl` item signature doesn't match `trait` item signature
  --> src/lib.rs:15:5
   |
5  |     fn iter(&self) -> I;
   |     -------------------- expected `fn(&MyStruct) -> Copied<std::collections::hash_set::Iter<'_, usize>>`
...
15 |     fn iter(&self) -> Iter<'_> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&MyStruct) -> Copied<std::collections::hash_set::Iter<'_, usize>>`
   |
   = note: expected `fn(&MyStruct) -> Copied<std::collections::hash_set::Iter<'_, _>>`
              found `fn(&MyStruct) -> Copied<std::collections::hash_set::Iter<'_, _>>`
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
  --> src/lib.rs:5:23
   |
5  |     fn iter(&self) -> I;
   |                       ^ consider borrowing this type parameter in the trait

“期望的”和“发现的”看起来是一样的,所以这可能是一个匿名生命周期的问题?我怎么才能让它工作呢?

Link to playground

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-12 19:11:22

问题是编译器不能在这里推断出正确的生命周期,所以你需要告诉它它们是什么,如下所示:

代码语言:javascript
复制
impl<'a> MyTrait<Iter<'a>> for MyStruct {
    fn iter(&'a self) -> Iter<'a> {
        self.set.iter().copied()
    }
}

不幸的是,您不能这样做,因为特征对self没有生命周期要求,所以实现者也不能。要实现这一点,您可以简单地将特征更改为:

代码语言:javascript
复制
trait MyTrait<'a, I: 'a + IntoIterator<Item = usize>> {
    fn iter(&'a self) -> I;
}

在这里,I: 'a + ...告诉编译器,I内部的任何引用都不能超过'a,即self

现在您可以像这样实现MyTrait

代码语言:javascript
复制
impl<'a> MyTrait<'a, Iter<'a>> for MyStruct {
    fn iter(&'a self) -> Iter<'a> {
        self.set.iter().copied()
    }
}

对于生存期并不重要的类型,因为I实际上并不包含任何引用,所以您仍然可以使用生存期省略:

代码语言:javascript
复制
impl MyTrait<'_, std::vec::IntoIter<usize>> for Vec<usize> {
    fn iter(&self) -> std::vec::IntoIter<usize> {
        self.clone().into_iter()
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68345709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档