Why is calling a FnOnce closure a move?
up vote
6
down vote
favorite
I'm trying to pass in a closure to a function that will then mutate something passed into it within the scope of the function. Based on my current understanding of Rust, that should look something like this:
pub fn call_something(callback: &FnOnce(&mut Vec<i32>))
let mut my_vec = vec![0, 1, 2, 3, 4];
callback(&mut my_vec);
That results in these errors:
error[E0161]: cannot move a value of type dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>): the size of dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>) cannot be statically determined
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^ cannot move out of borrowed content
Why is calling a FnOnce a move? What am I missing here?
rust closures move-semantics
add a comment |
up vote
6
down vote
favorite
I'm trying to pass in a closure to a function that will then mutate something passed into it within the scope of the function. Based on my current understanding of Rust, that should look something like this:
pub fn call_something(callback: &FnOnce(&mut Vec<i32>))
let mut my_vec = vec![0, 1, 2, 3, 4];
callback(&mut my_vec);
That results in these errors:
error[E0161]: cannot move a value of type dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>): the size of dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>) cannot be statically determined
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^ cannot move out of borrowed content
Why is calling a FnOnce a move? What am I missing here?
rust closures move-semantics
add a comment |
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I'm trying to pass in a closure to a function that will then mutate something passed into it within the scope of the function. Based on my current understanding of Rust, that should look something like this:
pub fn call_something(callback: &FnOnce(&mut Vec<i32>))
let mut my_vec = vec![0, 1, 2, 3, 4];
callback(&mut my_vec);
That results in these errors:
error[E0161]: cannot move a value of type dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>): the size of dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>) cannot be statically determined
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^ cannot move out of borrowed content
Why is calling a FnOnce a move? What am I missing here?
rust closures move-semantics
I'm trying to pass in a closure to a function that will then mutate something passed into it within the scope of the function. Based on my current understanding of Rust, that should look something like this:
pub fn call_something(callback: &FnOnce(&mut Vec<i32>))
let mut my_vec = vec![0, 1, 2, 3, 4];
callback(&mut my_vec);
That results in these errors:
error[E0161]: cannot move a value of type dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>): the size of dyn for<'r> std::ops::FnOnce(&'r mut std::vec::Vec<i32>) cannot be statically determined
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:3:5
|
3 | callback(&mut my_vec);
| ^^^^^^^^ cannot move out of borrowed content
Why is calling a FnOnce a move? What am I missing here?
rust closures move-semantics
rust closures move-semantics
edited Nov 9 at 22:08
Shepmaster
143k11268400
143k11268400
asked Nov 9 at 22:01
user96425
332
332
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
7
down vote
accepted
Why is calling a
FnOncea move?
Because that's the definition of what makes a closure FnOnce:
extern "rust-call" fn call_once(self, args: Args) -> Self::Output
// ^^^^
Contrast this to FnMut and Fn:
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output
// ^^^^^^^^^
extern "rust-call" fn call(&self, args: Args) -> Self::Output
// ^^^^^
See also:
- When does a closure implement Fn, FnMut and FnOnce?
- "cannot move a value of type FnOnce" when moving a boxed function
- Cannot move out of borrowed content
You probably want
pub fn call_something(callback: impl FnOnce(&mut Vec<i32>))
or
pub fn call_something<F>(callback: F)
where
F: FnOnce(&mut Vec<i32>),
These are identical. They both take ownership of the closure, which means that you can call the closure and consume it in the process.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
Why is calling a
FnOncea move?
Because that's the definition of what makes a closure FnOnce:
extern "rust-call" fn call_once(self, args: Args) -> Self::Output
// ^^^^
Contrast this to FnMut and Fn:
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output
// ^^^^^^^^^
extern "rust-call" fn call(&self, args: Args) -> Self::Output
// ^^^^^
See also:
- When does a closure implement Fn, FnMut and FnOnce?
- "cannot move a value of type FnOnce" when moving a boxed function
- Cannot move out of borrowed content
You probably want
pub fn call_something(callback: impl FnOnce(&mut Vec<i32>))
or
pub fn call_something<F>(callback: F)
where
F: FnOnce(&mut Vec<i32>),
These are identical. They both take ownership of the closure, which means that you can call the closure and consume it in the process.
add a comment |
up vote
7
down vote
accepted
Why is calling a
FnOncea move?
Because that's the definition of what makes a closure FnOnce:
extern "rust-call" fn call_once(self, args: Args) -> Self::Output
// ^^^^
Contrast this to FnMut and Fn:
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output
// ^^^^^^^^^
extern "rust-call" fn call(&self, args: Args) -> Self::Output
// ^^^^^
See also:
- When does a closure implement Fn, FnMut and FnOnce?
- "cannot move a value of type FnOnce" when moving a boxed function
- Cannot move out of borrowed content
You probably want
pub fn call_something(callback: impl FnOnce(&mut Vec<i32>))
or
pub fn call_something<F>(callback: F)
where
F: FnOnce(&mut Vec<i32>),
These are identical. They both take ownership of the closure, which means that you can call the closure and consume it in the process.
add a comment |
up vote
7
down vote
accepted
up vote
7
down vote
accepted
Why is calling a
FnOncea move?
Because that's the definition of what makes a closure FnOnce:
extern "rust-call" fn call_once(self, args: Args) -> Self::Output
// ^^^^
Contrast this to FnMut and Fn:
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output
// ^^^^^^^^^
extern "rust-call" fn call(&self, args: Args) -> Self::Output
// ^^^^^
See also:
- When does a closure implement Fn, FnMut and FnOnce?
- "cannot move a value of type FnOnce" when moving a boxed function
- Cannot move out of borrowed content
You probably want
pub fn call_something(callback: impl FnOnce(&mut Vec<i32>))
or
pub fn call_something<F>(callback: F)
where
F: FnOnce(&mut Vec<i32>),
These are identical. They both take ownership of the closure, which means that you can call the closure and consume it in the process.
Why is calling a
FnOncea move?
Because that's the definition of what makes a closure FnOnce:
extern "rust-call" fn call_once(self, args: Args) -> Self::Output
// ^^^^
Contrast this to FnMut and Fn:
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output
// ^^^^^^^^^
extern "rust-call" fn call(&self, args: Args) -> Self::Output
// ^^^^^
See also:
- When does a closure implement Fn, FnMut and FnOnce?
- "cannot move a value of type FnOnce" when moving a boxed function
- Cannot move out of borrowed content
You probably want
pub fn call_something(callback: impl FnOnce(&mut Vec<i32>))
or
pub fn call_something<F>(callback: F)
where
F: FnOnce(&mut Vec<i32>),
These are identical. They both take ownership of the closure, which means that you can call the closure and consume it in the process.
edited Nov 9 at 22:39
answered Nov 9 at 22:09
Shepmaster
143k11268400
143k11268400
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233803%2fwhy-is-calling-a-fnonce-closure-a-move%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown