如何从trait方法的HashSet的键上返回迭代器?

时间:2019-12-17 14:20:01

标签: rust

一个结构包含一组我想让客户迭代的项目。这是一个尝试:

use std::collections::HashSet;
use std::hash::Hash;

pub struct Foo<T: Eq + Hash> {
    items: HashSet<T>,
}

impl<'a, T: 'a + Eq + Hash> Foo<T> {
    pub fn new() -> Self {
        Foo {
            items: HashSet::new(),
        }
    }

    pub fn iterate<I>(&self) -> I
    where
        I: IntoIterator<Item = &'a T>,
    {
        self.items.iter()
    }
}

这无法编译,并显示错误:

error[E0308]: mismatched types
  --> src/lib.rs:19:9
   |
15 |     pub fn iterate<I>(&self) -> I
   |                                 - expected `I` because of return type
...
19 |         self.items.iter()
   |         ^^^^^^^^^^^^^^^^^ expected type parameter, found struct `std::collections::hash_set::Iter`
   |
   = note: expected type `I`
              found type `std::collections::hash_set::Iter<'_, T>`
   = help: type parameters must be constrained to match other types
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

例如在for循环内,HashSet::iter方法的返回值看起来像Iterator。在我的iterate方法中似乎可以进行某种类型的强制转换,但显然编译器还有其他想法。

如何在从Iterator迭代器返回返回值的同时,在函数中指定HashSet的返回类型?

换句话说,我想将迭代委托给HashSet。我想避免实现自定义迭代器来执行此操作,但是如果那是唯一的方式,则希望了解它的完成方式。我已经可以通过返回Box<dyn Iterator>来使它正常工作,但是如果可以像this answer所述仅使用特征边界,我也想避免这种方法。

另一个要求:在特征上声明iterate方法时,该方法必须有效。看来可以排除以下方法:

pub trait FooTrait {
    fn iterate(&self) -> impl Iterator<Item=&T>;
}

1 个答案:

答案 0 :(得分:0)

您要impl Iterator

impl<'a, T: 'a + Eq + Hash> Foo<T> {
    // ...

    pub fn iterate(&'a self) -> impl Iterator<Item = &'a T> {
        self.items.iter()
    }
}

Rust书中有this section对此进行了介绍。它在RFC 1522RFC 1951RFC 2071中定义和完善。尚未完成,有this tracking issue