返回结构的类型不匹配(预期<k,v =“”>,找到&lt;&amp; K,&amp; V&gt;)

时间:2016-11-26 01:02:25

标签: rust

给出以下代码(目前还没有做太多):

use std::collections::BTreeMap;
use std::iter::FromIterator;

trait Node<K, V> {
    fn split(&self) -> Split<K, V>;
}

#[derive(Debug, Copy, Clone)]
pub struct Config {
    data_b: usize,
}

struct Split<'a, K, V> {
    left: Box<Node<K, V> + 'a>,
    right: Box<Node<K, V> + 'a>,
}

#[derive(Debug)]
pub struct DataNode<K, V> {
    cfg: Config,
    children: BTreeMap<K, V>,
}

impl<K: Clone + Ord, V: Clone> Node<K, V> for DataNode<K, V> {
    fn split(&self) -> Split<K, V> {
        let data_b = self.cfg.data_b;

        Split {
            left: Box::new(DataNode {
                cfg: self.cfg.clone(),
                children: BTreeMap::from_iter(self.children.iter().take(data_b))
            }),
            right: Box::new(DataNode {
                cfg: self.cfg.clone(),
                children: BTreeMap::from_iter(self.children.iter().rev().take(data_b))
            }),
        }
    }
}

编译器出现以下错误:

error[E0308]: mismatched types
  --> lib.rs:68:9
   |
68 |         Split {
   |         ^ expected type parameter, found &K
   |
   = note: expected type `Split<'_, K, V>`
   = note:    found type `Split<'_, &K, &V>`

我对Rust很新,所以我不确定是什么导致了这一点。为了绝对清楚,我遇到的问题是关于错误消息的含义。显然,这意味着我没有返回正确的类型。问题是为什么编译器将此Split {...}代码解释为当我期望Split<'_, &K, &V>时返回Split<'_, K, V>的代码。任何见解都表示赞赏。

1 个答案:

答案 0 :(得分:2)

引用来自您在子项上迭代以构建新BTreeMap

的位置
BTreeMap::from_iter(self.children.iter().take(data_b))

如果您查看iterator returned by BTreeMap::iter(),则Item类型为:

type Item = (&'a K, &'a V)

即。迭代器返回对内容的引用对。这是有道理的,因为您不希望在迭代时将项目移出地图,或者依赖Copy

这与例如Vec::iter(),是一对引用,而不是对一对的引用。这确实有意义,因为对一对的引用意味着容器必须在内部实际包含这些对(限制内部数据结构)。

最简单的方法是克隆键和值:

BTreeMap::from_iter(self.children.iter()
                                 .map(|(&a, &b)| (a.clone(), b.clone()))
                                 .take(data_b))