【发布时间】:2016-10-21 00:00:29
【问题描述】:
我在尝试编译下面的 Rust 代码时遇到了一对奇怪的错误。在寻找其他有类似问题的人时,我遇到了another question with the same combination of (seemingly opposing) errors,但无法将那里的解决方案推广到我的问题。
基本上,我似乎遗漏了 Rust 所有权系统的一个微妙之处。在这里尝试编译(非常精简的)代码:
struct Point {
x: f32,
y: f32,
}
fn fold<S, T, F>(item: &[S], accum: T, f: F) -> T
where
F: Fn(T, &S) -> T,
{
f(accum, &item[0])
}
fn test<'a>(points: &'a [Point]) -> (&'a Point, f32) {
let md = |(q, max_d): (&Point, f32), p: &'a Point| -> (&Point, f32) {
let d = p.x + p.y; // Standing in for a function call
if d > max_d {
(p, d)
} else {
(q, max_d)
}
};
fold(&points, (&Point { x: 0., y: 0. }, 0.), md)
}
我收到以下错误消息:
error[E0631]: type mismatch in closure arguments
--> src/main.rs:23:5
|
14 | let md = |(q, max_d): (&Point, f32), p: &'a Point| -> (&Point, f32) {
| ---------------------------------------------------------- found signature of `for<'r> fn((&'r Point, f32), &'a Point) -> _`
...
23 | fold(&points, (&Point { x: 0., y: 0. }, 0.), md)
| ^^^^ expected signature of `for<'r> fn((&Point, f32), &'r Point) -> _`
|
= note: required by `fold`
error[E0271]: type mismatch resolving `for<'r> <[closure@src/main.rs:14:14: 21:6] as std::ops::FnOnce<((&Point, f32), &'r Point)>>::Output == (&Point, f32)`
--> src/main.rs:23:5
|
23 | fold(&points, (&Point { x: 0., y: 0. }, 0.), md)
| ^^^^ expected bound lifetime parameter, found concrete lifetime
|
= note: required by `fold`
(A Rust Playground link for this code, for convenience.)
在我看来,我提供给 fold 的函数应该正确地进行类型检查......我在这里遗漏了什么,我该如何修复它?
【问题讨论】:
-
两个注意事项:99.99% 的时间使用
&[T]而不是&Vec<T>。另外,当一个空向量被传递给它时,你的test函数会发生什么?该参考将在哪里出现? -
@Shepmaster 所以我实际上使用
Vec<T>来代替我正在处理的自定义函数式列表类型,只是为了保持问题简单并专注于我的错误米得到。此外,在我的代码的非精简版本中,一个空列表panic!s 并表示无事可做。基本上,我试图将代码减少到我仍然会收到错误消息而忽略任何无关内容的程度。 -
那很好,减少问题也很棒!但是,当前的 MCVE 尝试返回对局部变量的引用,这将导致生命周期错误,可能阻止我给你答案,因为我无法编译它。而且你不应该让你的手指输入
&Vec<T>,所以它甚至不应该出现在一个例子中^_^。 -
出于好奇,为什么 &[T] 优于 &Vec
?