n. *_* m. 2 reference fold rust
(这里是生锈菜鸟;我试图了解在高阶函数情况下可以/不能/应该/不应该通过引用传递什么)
let a = [1, 2, 3];
Run Code Online (Sandbox Code Playgroud)
此调用有效:
let sum = a.iter().fold(0, |acc: i32, x: &i32| acc + x);
Run Code Online (Sandbox Code Playgroud)
这些不:
let sum = a.iter().fold(0, |acc: i32, x: i32| acc + x);
let sum = a.iter().fold(0, |acc: &i32, x: i32| acc + x);
Run Code Online (Sandbox Code Playgroud)
错误信息是
error[E0631]: type mismatch in closure arguments
--> main.rs:8:22
|
8 | let sum = a.iter().fold(0, |acc: &i32, x: i32| acc + x);
| ^^^^ --------------------------- found signature of `for<'r> fn(&'r i32, i32) -> _`
| |
| expected signature of `fn({integer}, &{integer}) -> _`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0631`.
Run Code Online (Sandbox Code Playgroud)
该解释没有提供任何有趣的内容。它表示闭包的参数与 的参数不匹配fold。然而,我看不出它是如何从声明中得出的fold:
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B
Run Code Online (Sandbox Code Playgroud)
为什么第二个参数应该是&{integer},而第一个参数应该是{integer}?
迭代器中的项是从数组借用的,因此&i32不是i32。这种形式之所以有效,是因为累加器是拥有的,而物品是借用的:
let sum = a.iter().fold(0, |acc: i32, x: &i32| acc + x);
Run Code Online (Sandbox Code Playgroud)
您可以转换迭代器,以便复制而不是引用其项目,然后第一种形式将起作用:
let sum = a.iter().copied().fold(0, |acc: i32, x: i32| acc + x);
Run Code Online (Sandbox Code Playgroud)
第三种形式永远行不通。闭包需要能够返回一个新值来更新累加器。累加器的类型是i32。它不能是引用,因为你不能从闭包返回引用(原始值将被删除,Rust 不会让你返回悬空指针)。
| 归档时间: |
|
| 查看次数: |
583 次 |
| 最近记录: |