2017-09-05 30 views
1

我已經寫了一個函數來映射向量。該方法定義預計3個泛型參數,並定義了一個輸入向量和函數:期望的類型參數,找到&預期A

pub fn map<F, A, B>(mapFn: F, vect: &[A]) -> &[B] 
where 
    F: Fn(A) -> B, 
{ 
    let mut list = vec![]; 

    for v in vect { 
     let mut value = mapFn(v); 
     list.push(value); 
    } 

    &list[..] 
} 

我得到這個錯誤:

error[E0308]: mismatched types 
--> src/main.rs:8:31 
    | 
8 |   let mut value = mapFn(v); // <------ This is where I get the error 
    |        ^expected type parameter, found &A 
    | 
    = note: expected type `A` 
      found type `&A` 

我也查Generics Error: expected type parameter, found struct,但它似乎沒有大致相同問題。

+2

我看不到你的功能的興趣。這種方法已經存在。 – Boiethios

回答

3

您的代碼有幾個問題。鏽病的所有權模式是艱難的,但公平...


其中主要的一個(不直接導致你的錯誤)是這樣的:

let mut list = vec![]; // allocate in a function 
// [cut] 
&list[..] // return a reference to memory allocated in the function 
      // ... which gets freed at the end of the function 
      // (if this compiled you'd have a dangling reference) 

修復返回Vec直接


第二個(這個直接解決你的錯誤):你試圖從一個切片中取出元素(vect),將它們放入一個新的矢量(list)並返回新的矢量。像vect這樣的片不擁有它的元素,所以它可以給你引用,但listVec,所以它想要擁有它的元素。

修復爲了有原始元素的國有版本,你必須要麼:

  1. vect包含可以Clone(這樣你就可以保存它們的副本在新項目向量)。這限制了您函數的通用性(並非所有類型都是Clone -able)。您可以通過添加綁定到您的函數簽名的A: Clone並調用mapFn(v.clone())
  2. 使函數完全擁有所有權以開始,即使輸入參數爲vect: Vec<A>。這樣做的缺點是,當您將元素從vect移動到list時,vect不再可用。

playground


注意,鏽病標準庫定義map on iterators,它是一個更靈活的方法。它在迭代輸入的同時逐個元素應用函數,因此它不需要擁有或克隆元素。

1

首先,有一個map adaptor for iterators

你的問題在於mapFn期望一個擁有的價值,但是迭代在一個切片上(& [A])爲你提供參考。

您可以將Vec作爲參數或使fnMap接受& A來解決您的問題。

最後,返回一個ref並不是你想要的,你可以直接返回Vec。

相關問題