我如何在克隆密钥的HashMap的密钥上返回迭代器?

时间:2019-08-26 20:54:23

标签: rust hashmap iterator clone

我正在定义一个名为ShyAssociation的特征,该特征返回关联结构键的惰性迭代器。迭代器应借用不可变的密钥或将其克隆。键始终是&'static str.,我所需要的只是一个返回&'static str的迭代器。

这是我尝试使用keys迭代器的方法的特征:

use std::collections::{hash_map::Keys, HashMap};

#[derive(Clone, PartialEq, Debug)]
pub enum ShyValue {
    Boolean(bool),
    Integer(i64),
    Rational(f64),
    String(String),
    Error(String),
}

pub trait ShyAssociation {
    fn keys(&self) -> Keys<&'static str, ShyValue>;
}

impl ShyAssociation for HashMap<&'static str, ShyValue> {
    fn keys(&self) -> Keys<&'static str, ShyValue> {
        self.keys().cloned()
    }
}

它不会编译。

error[E0308]: mismatched types
  --> src/lib.rs:18:9
   |
18 |         self.keys().cloned()
   |         ^^^^^^^^^^^^^^^^^^^^ expected struct `std::collections::hash_map::Keys`, found struct `std::iter::Cloned`
   |
   = note: expected type `std::collections::hash_map::Keys<'_, &'static str, _>`
              found type `std::iter::Cloned<std::collections::hash_map::Keys<'_, &str, _>>`

更新:

我正在尝试对Alexander Huszagh的答案进行修改,但语法有错误:

use std::collections::{hash_map::Keys, HashMap};

#[derive(Clone, PartialEq, Debug)]
pub enum ShyValue {
    Boolean(bool),
    Integer(i64),
    Rational(f64),
    String(String),
    Error(String),
}

pub trait ShyAssociation<'a> {
    fn keys(&self) -> Box<Iterator<Item=&'static str> + 'a>;
}

impl<'a> ShyAssociation<'a> for HashMap<&'static str, ShyValue> {
    fn keys(&self) -> Box<Iterator<Item=&'static str> + 'a> {
        Box::new<(Iterator<Item=&'static str> + 'a)>(self.keys().cloned())
    }
}

错误消息在键的迭代器项定义的“ str”上:

expected `:`, found `str`

expected `:`rustc
shy_association.rs(59, 42): expected `:`

1 个答案:

答案 0 :(得分:3)

问题是您要手动指定与返回类型不匹配的类型。 iter::Cloned<Keys<_, _>>Keys<_, _>不同。一个简单的解决方法是将您的退货类型更改为iter::Cloned<Keys<&'static str, ShyValue>>

pub trait ShyAssociation {
    fn keys(&self) -> iter::Cloned<Keys<&'static str, ShyValue>>;
}

impl ShyAssociation for HashMap<&'static str, ShyValue> {
    fn keys(&self) -> iter::Cloned<Keys<&'static str, ShyValue>> {
        self.keys().cloned()
    }
}

如果要返回实现特征的类型(在上例中将不起作用,因为这仅对非特征函数和方法有效),您也可以这样做:

pub fn keys<'a>(hash_map: &'a HashMap<&'static str, ShyValue>) -> impl Iterator<Item = &'a str> {
    hash_map.keys().cloned()
}

如果您想使用Box<dyn Iterator>,以便可以在特征方法中使用它,可以这样做:

pub trait ShyAssociation {
    fn keys<'a>(&'a self) -> Box<(dyn Iterator<Item = &'static str> + 'a)>;
}

impl ShyAssociation for HashMap<&'static str, ShyValue> {
    fn keys<'a>(&'a self) -> Box<(dyn Iterator<Item = &'static str> + 'a)> {
        Box::new(self.keys().cloned())
    }
}

为了将迭代器的生存期限制为'a的生存期,HashMap生存期是必需的。