简体   繁体   English

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

[英]Mismatched types for returned struct (expected <K, V>, found <&K, &V>)

Given the following code (which doesn't do much yet): 给出以下代码(目前尚不完善):

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))
            }),
        }
    }
}

The compiler gives the following error: 编译器给出以下错误:

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>`

I'm pretty new to Rust so I'm not sure what's causing this. 我对Rust还是很陌生,所以我不确定是什么原因造成的。 To be absolutely clear, the question I'm having is not about what the error message means . 绝对清楚地说,我所遇到的问题与错误消息的含义 无关 Clearly, it means that I'm not returning the right type. 显然,这意味着我没有返回正确的类型。 The question is why does the compiler interpret this Split {...} code as code that returns Split<'_, &K, &V> when I expect it to be Split<'_, K, V> . 现在的问题是,为什么编译器解释这种Split {...}代码返回代码Split<'_, &K, &V>时,我希望它是Split<'_, K, V> Any insight is appreciated. 任何见解均表示赞赏。

The references come from where you iterate on the child to build a new BTreeMap : 引用来自您在子级上迭代以构建新的BTreeMap

BTreeMap::from_iter(self.children.iter().take(data_b))

If you look at the iterator returned by BTreeMap::iter() , the Item type is: 如果查看BTreeMap::iter()返回迭代器 ,则Item类型为:

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

ie the iterator returns pairs of references to the contents. 即,迭代器返回对内容的引用对。 This makes sense, because you don't want to move items out of the map when iterating, or rely on Copy . 这是有道理的,因为您不想在迭代时将项目移出地图,也不必依靠Copy

This is slightly different from eg Vec::iter() , being a pair of references rather than a reference to a pair. 这与例如Vec::iter()稍有不同, Vec::iter()是一对引用而不是一对引用。 This does make sense, as a reference to a pair would mean the container would have to actually contain those pairs internally (restricting the internal data structure). 这确实是有道理的,因为对对的引用意味着容器将必须实际上在内部包含那些对(限制内部数据结构)。

The simplest thing is to clone the key and value: 最简单的事情是克隆键和值:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM