预期的类型参数,找到& A预期的A.

时间:2017-09-05 07:13:40

标签: generics rust

我编写了一个映射向量的函数。方法定义需要3个通用参数,并定义输入向量和函数:

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 个答案:

答案 0 :(得分:3)

您的代码存在一些问题。 Rust的所有权模式很难但很公平......

主要的一个(不直接导致你的错误)是:

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 - 能够)。您可以通过添加A: Clone绑定到您的函数签名并调用mapFn(v.clone())
  2. 来实现它
  3. 为函数提供完全的数据所有权,即输入参数为vect: Vec<A>。这样做的缺点是,当您将元素从vect移动到list时,vect将不再可用。
  4. playground

    请注意,Rust标准库定义了map on iterators,这是一种更灵活的方法。它在迭代输入时逐个元素地应用函数,因此它不需要拥有或克隆元素。

答案 1 :(得分:1)

首先,有一个map adaptor for iterators

你的问题在于mapFn期望一个拥有的值,但迭代切片(&amp; [A])会给你refs。

您可以将Vec作为参数或使fnMap接受&amp; A来解决您的问题。

最后,返回一个ref不是你想要的,你可以返回普通的Vec。