【问题标题】:"wrong number of type arguments" when implementing IntoIterator that returns HashMap::IntoIter实现返回 HashMap::IntoIter 的 IntoIterator 时出现“类型参数数量错误”
【发布时间】:2020-08-21 16:20:52
【问题描述】:

我有以下代码:

use std::{collections::HashMap, hash::Hash, rc::Rc};

#[derive(Debug)]
pub struct LFUCache<K: Hash + Eq, V> {
    values: HashMap<Rc<K>, ValueCounter<V>>,
    capacity: usize,
    min_frequency: usize,
}

#[derive(Debug)]
struct ValueCounter<V> {
    value: V,
    count: usize,
}

impl<K: Hash + Eq, V> IntoIterator for LFUCache<K, V> {
    type Item = (Rc<K>, V);
    type IntoIter = std::collections::HashMap::IntoIter<Rc<K>, V>;

    fn into_iter(self) -> Self::IntoIter {
        return self
            .values
            .into_iter()
            .map(|(key, valueCounter)| (key, valueCounter.value));
    }
}

它抛出一个错误说:

error[E0107]: wrong number of type arguments: expected at least 2, found 0
  --> src/lib.rs:18:21
   |
18 |     type IntoIter = std::collections::HashMap::IntoIter<Rc<K>, V>;
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at least 2 type arguments

我查看了文档,我的用例似乎与 to the example 非常相似。

我该如何解决这个问题?

【问题讨论】:

  • 顺便说一句,惯用的 Rust 使用 snake_case 表示变量、方法、宏、字段和模块; UpperCamelCase 用于类型和枚举变体; SCREAMING_SNAKE_CASE 用于静态和常量。

标签: rust hashmap iterator


【解决方案1】:

HashMap::IntoIter,来自 IntoIterator 特征的关联类型,没有任何类型参数。 HashMap 确实HashMap::&lt;Rc&lt;K&gt;, V&gt;::IntoIter。这是模棱两可的,所以你必须完全限定它:

type IntoIter = <std::collections::HashMap::<Rc<K>, V> as IntoIterator>::IntoIter;

这通常表示为

type IntoIter = std::collections::hash_map::IntoIter<Rc<K>, V>;

然后你遇到了你试图对编译器撒谎的问题,因为你没有返回那个类型

error[E0308]: mismatched types
  --> src/lib.rs:21:9
   |
21 | /         self.values
22 | |             .into_iter()
23 | |             .map(|(key, valueCounter)| (key, valueCounter.value))
   | |_________________________________________________________________^ expected struct `std::collections::hash_map::IntoIter`, found struct `std::iter::Map`
   |
   = note: expected struct `std::collections::hash_map::IntoIter<_, V>`
              found struct `std::iter::Map<std::collections::hash_map::IntoIter<_, ValueCounter<V>>, [closure@src/lib.rs:23:18: 23:65]>`

根据链接问题的提示,您最终会得到

use std::{collections::hash_map::IntoIter, iter::Map};

impl<K: Hash + Eq, V> IntoIterator for LFUCache<K, V> {
    type Item = (Rc<K>, V);
    type IntoIter =
        Map<IntoIter<Rc<K>, ValueCounter<V>>, fn((Rc<K>, ValueCounter<V>)) -> (Rc<K>, V)>;

    fn into_iter(self) -> Self::IntoIter {
        fn xform<K, V>((key, vc): (Rc<K>, ValueCounter<V>)) -> (Rc<K>, V) {
            (key, vc.value)
        }

        self.values.into_iter().map(xform)
    }
}

另见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多