这个想法是有一个闭包(在本例中为change_x
)捕获状态(在本例中为x
),该状态以一个函数作为其参数(alterer
),该函数将指示内部状态如何变化。
pub fn plus17(h: & u64) -> u64 {
*h + 17
}
pub fn main() {
let x = 0; //take x by reference
let mut change_x = move |alterer: &dyn FnOnce(&u64) ->u64 | alterer(&x) ;
change_x(&mut plus17);
println!("{}", x);
}
我似乎不能把类型正确然而:
error[E0161]: cannot move a value of type dyn for<'r> FnOnce(&'r u64) -> u64: the size of dyn for<'r> FnOnce(&'r u64) -> u64 cannot be statically determined
--> playground/src/main.rs:19:69
|
19 | let mut increment_x = move |alterer: &dyn FnOnce(&u64) ->u64 | alterer(&x) ;
| ^^^^^^^
error[E0507]: cannot move out of `*alterer` which is behind a shared reference
--> playground/src/main.rs:19:69
|
19 | let mut increment_x = move |alterer: &dyn FnOnce(&u64) ->u64 | alterer(&x) ;
| ^^^^^^^ move occurs because `*alterer` has type `dyn for<'r> FnOnce(&'r u64) -> u64`, which does not implement the `Copy` trait
我不确定我是否有理由把dyn
放在我放它的地方,这是一个编译器的建议,我不确定为什么我要把它放在那里。这是因为alterer
可以是任意大小,尽管&u64->u64
的输入/返回类型?
我也试过让一个FnMut
而不是FnOnce
,但我也很不确定它们的区别,一个给定的alterer
只运行一次(在外部闭包change_x
调用的时刻)似乎是合理的。
FnOnce
需要一个拥有的self
。因此,alterer
不可能是FnOnce
,因为它不是私有的,而是一个引用。
你可以选择&dyn Fn
或&mut dyn FnMut
(我建议你选择FnMut
),或者选择Box<dyn FnOnce>
。