2016-11-26 62 views
0

考慮下面的代碼(這並沒有做太多尚未):類型不匹配的返回結構(預計<K, V>,發現<&K, &V>)

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>的代碼。任何見解都會被讚賞。

+0

你明白[*什麼引用*](https://doc.rust-lang.org/stable/book/references-和borrowing.html)?你知道['BTreeMap :: iter'](https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.iter)是如何工作的嗎?國際海事組織,錯誤信息是非常簡單的 - 你說過你會回報一件事,但你回來了別的東西。我們可以進一步澄清哪些信息缺失? – Shepmaster

+0

我沒有說我不明白錯誤信息。我不明白的是爲什麼我在'Split <'_, &K, &V>'中寫過結果。如果它與使用迭代器的細微之處有關,那麼,這超出了我的Rust知識水平,我希望有一些洞察力。在來這裏之前,我能做的最好的事情是檢查返回什麼類型的東西,但什麼都沒有表明引用會起作用。所以不知何故,編譯器覺得不得不做出這樣的要求,我想了解爲什麼以及如何才能得到我想要的,如果可能的話。 – neverfox

回答

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(),是一對參考文獻,而不是一對參考文獻。這是有道理的,因爲對pair的引用意味着容器必須在內部實際包含這些對(限制內部數據結構)。

最簡單的事情是克隆鍵和值:

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

感謝您的明確解釋並指出可能的解決方案。你說得對,它確實有道理。我在所有使用的各種方法中檢查了類型,但我被文檔誤導,說'fn iter(&self) - > Iter '所以我正在抓我的頭。現在我知道我應該在哪裏尋找。 – neverfox

+1

我在網上文檔中做了很多點擊類型!你學習各種各樣的東西。 –

相關問題