Difference between (|| var) and (move || var.clone())
⚓ Rust 📅 2025-09-09 👤 surdeus 👁️ 8Why does (move || args.path.clone()) work, but (|| args.path) doesn't in the following code? What's the difference between them?
cargo add bevy
use std::path::PathBuf;
use bevy::prelude::*;
struct Args {
path: PathBuf,
}
fn main() {
let args: Args = Args { path: default() };
App::new()
.add_plugins(MinimalPlugins)
/*
error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
--> src/main.rs:29:32
|
29 | .add_systems(Startup, (|| args.path).pipe(startup))
| -^^----------- ---- required by a bound introduced by this call
| || |
| || closure is `FnOnce` because it moves the variable `args.path` out of its environment
| |this closure implements `FnOnce`, not `FnMut`
| the requirement to implement `FnMut` derives from here
|
= note: required for `&'a mut {closure@src/main.rs:29:32: 29:34}` to implement `for<'a> FnOnce()`
= note: required for `{closure@src/main.rs:29:32: 29:34}` to implement `bevy::prelude::SystemParamFunction<fn() -> PathBuf>`
= note: required for `{closure@src/main.rs:29:32: 29:34}` to implement `bevy::prelude::IntoSystem<(), PathBuf, (IsFunctionSystem, fn() -> PathBuf)>`
*/
//.add_systems(Startup, (|| args.path).pipe(startup))
// This works.
.add_systems(Startup, (move || args.path.clone()).pipe(startup))
.run();
}
fn startup(In(path): In<PathBuf>) {
println!("{path:?}");
}
3 posts - 2 participants
🏷️ Rust_feed