作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(rust noob here;我试图理解在高阶函数情况下什么可以/不能/应该/不应该通过引用传递)
let a = [1, 2, 3];
此调用有效:
let sum = a.iter().fold(0, |acc: i32, x: &i32| acc + x);
这些不:
let sum = a.iter().fold(0, |acc: i32, x: i32| acc + x);
let sum = a.iter().fold(0, |acc: &i32, x: i32| acc + x);
错误信息是
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`.
解释没有提供任何有趣的东西。它表示闭包的参数与 fold
的参数不匹配。然而,我看不到它是如何从 fold
的声明中得出的:
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B
为什么第二个参数应该是&{integer}
,而第一个参数应该是{integer}
?
最佳答案
迭代器中的项是从数组中借用的,所以&i32
不是i32
。这种形式之所以有效,是因为蓄能器是自己的,而元素是借来的:
let sum = a.iter().fold(0, |acc: i32, x: &i32| acc + x);
您可以转换迭代器,使其项被复制而不是被引用,然后第一种形式将起作用:
let sum = a.iter().copied().fold(0, |acc: i32, x: i32| acc + x);
第三种形式永远行不通。闭包需要能够返回一个新值来更新累加器。累加器的类型是 i32
。它不能是引用,因为你不能从闭包中返回引用(原始值将被丢弃,Rust 不会让你返回悬空指针)。
关于rust - fold 对它接受的闭包很挑剔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63378620/
我是一名优秀的程序员,十分优秀!