闭包在其状态中有一些数据,但我如何使其变为可变?例如,我想要一个计数器闭包,每次都返回递增的值,但它不起作用.我如何使其工作?
fn counter() -> Box<Fn() -> i32> {
let mut c: i32 = 0;
Box::new(move || {
c += 1;
c
})
}
fn main() {
let mut a = counter();
let mut b = counter();
println!("{:?}", [a(), a(), a(), b(), b(), a()]);
}
Run Code Online (Sandbox Code Playgroud)
错误(和警告)我得到:
error: cannot assign to captured outer variable in an `Fn` closure
c += 1;
^~~~~~
help: consider changing this closure to take self by mutable reference
Box::new(move || {
c += 1;
c
})
Run Code Online (Sandbox Code Playgroud)
我希望它输出类似的东西[1, 2, 3, 1, 2, 4].
She*_*ter 10
正如错误消息所示:
无法在
Fn闭包中分配捕获的外部变量
相反,你想要一个FnMut闭包:
fn counter() -> Box<FnMut() -> i32> {
let mut c = 0;
Box::new(move || {
c += 1;
c
})
}
fn main() {
let mut a = counter();
let mut b = counter();
let result = [a(), a(), a(), b(), b(), a()];
println!("{:?}", result);
assert_eq!([1, 2, 3, 1, 2, 4], result);
}
Run Code Online (Sandbox Code Playgroud)
正如FnMut文档所说:
采用可变接收器的呼叫运算符的一个版本.
这允许闭包改变包含的状态.
顺便说一句,c不需要显式类型.
令我困惑的是,那是
pub trait Fn<Args>: FnMut<Args>.这不是指Fn(我用过的)应该支持的行为FnMut吗?
也许封闭什么时候实现Fn,FnMut和FnOnce?可以帮助提供一些背景信息.这是我直观的一个方面,但还没有弄清楚如何最好的沟通.Rust中的Finding Closure的这一部分似乎也很相关:
在高层次上
self,实施者(即用户定义的用于实现特征的类型)具有最大的灵活性,具有&mut self下一个和&self最不灵活的特性.相反,&self给予消费者特征(即具有特征限制的仿制药的功能)最灵活,self最少.
简而言之,该特征定义表明任何FnMut闭包都可以用作Fn闭包.这是有道理的,因为我们可以简单地忽略可变性.你不能走另一条路 - 你不能将一个不可变的引用变成一个可变的引用.
| 归档时间: |
|
| 查看次数: |
3554 次 |
| 最近记录: |