我有以下Rust MCVE:
#[derive(Clone)]
struct X {
x: i32,
}
fn fold1<I: Iterator, F>(mut it: I, f: F) -> I::Item
where
I::Item: Clone,
F: FnMut(I::Item, I::Item) -> I::Item,
{
let init = it.next().unwrap().clone();
it.fold(init, f)
}
fn main() {
let v = vec![X { x: 1 }, X { x: 2 }];
// This does not compile:
let s = fold1(v.iter(), |a, b| X { x: a.x + b.x });
println!("{}", s.x);
}
字符串
这不会编译,并出现以下错误:
error[E0308]: mismatched types
--> example.rs:19:36
|
19 | let s = fold1(v.iter(), |a, b| X { x: a.x + b.x });
| ^^^^^^^^^^^^^^^^^^ expected `&X`, found `X`
|
help: consider borrowing here
|
19 | let s = fold1(v.iter(), |a, b| &X { x: a.x + b.x });
| +
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
型
但是,如果我手动内联函数:
#[derive(Clone)]
struct X {
x: i32,
}
fn main() {
let v = vec![X { x: 1 }, X { x: 2 }];
// The inlined version, however, does:
let mut it = v.iter();
let init = it.next().unwrap().clone();
let s = it.fold(init, |a, b| X { x: a.x + b.x });
println!("{}", s.x);
}
型
那么一切都很好。代码编译并做了预期的事情。
我真的看不出有什么不同。我做错什么了?
(And,作为后续,是否有可能编写一个类似fold1
的函数,克隆迭代器的第一个元素,然后将其用作fold
的初始元素?不,reduce
不是答案。在迭代器上调用cloned()
也不是答案。我真的只想克隆 * 第一个 *,而不是所有的。)
1条答案
按热度按时间yzuktlbb1#
在你的工作代码中,你正在调用
fold::<X, FnMut (X, &X) -> X>
,但在非工作情况下,你试图调用fold::<&X, FnMut (&X, &X) -> &X>
,因为I::Item
是&X
。这不起作用,因为你的闭包的返回类型与初始值fold
不一样。你需要修改fold1
的声明,使其与工作代码匹配:字符串
Playground