我编写了一个映射向量的函数。方法定义需要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,但似乎并没有出现同样的问题。
答案 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
这样的切片不拥有其元素,因此它可以为您提供所有引用,但list
是Vec
,因此它希望拥有其元素。
修复要拥有原始元素的自有版本,您必须:
vect
包含您可以Clone
的项目(这样您就可以将它们的副本存储在新的向量中)。这限制了函数的通用性(并非所有类型都是Clone
- 能够)。您可以通过添加A: Clone
绑定到您的函数签名并调用mapFn(v.clone())
vect: Vec<A>
。这样做的缺点是,当您将元素从vect
移动到list
时,vect
将不再可用。请注意,Rust标准库定义了map on iterators,这是一种更灵活的方法。它在迭代输入时逐个元素地应用函数,因此它不需要拥有或克隆元素。
答案 1 :(得分:1)
首先,有一个map adaptor for iterators。
你的问题在于mapFn期望一个拥有的值,但迭代切片(&amp; [A])会给你refs。
您可以将Vec作为参数或使fnMap接受&amp; A来解决您的问题。
最后,返回一个ref不是你想要的,你可以返回普通的Vec。