You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So apparently the changes to make the trait Copy opt-in for closures have been implemented, which means that the code above doesn't work any more.
But can somebody explain how I can actually opt-in for the Copy trait when declaring a closure?
But can somebody explain how I can actually opt-in for the Copy trait when declaring a closure?
There's a few possible ways to have duplicatable closures (all aren't great, unfortunately):
pass a & reference instead of the closure itself (&F implements Fn when F itself does), which implements Copy
use Rc<F> (possibly a trait object), similar to the above, but this can be stored/returned (only implements Clone
write fn foo<F, G>(f: F) where F: Fn() -> G, G: Fn(...) -> ... instead of fn foo<F>(f: F) where F: Fn(...) -> ..., where the F closure creates new instances of the actual closure of interest (G), effectively behaving as the clone function. I suspect this often works as just foo(|| |actual| closure), i.e. just add || at the start of the closure.
These have various downsides e.g. the first two only work for Fn (not FnMut or FnOnce), the first cannot be returned from functions/stored inside return values, the second doesn't integrate with generics quite as well as others, and the third is rather ugly.
Activity
japaric commentedon Dec 15, 2014
This is solved, unboxed closures are currently copyable:
But according to #19817 and #19889, the plan is that they shouldn't be implicitly copyable (which I don't quite agree with).
ghost commentedon Jan 11, 2015
So apparently the changes to make the trait Copy opt-in for closures have been implemented, which means that the code above doesn't work any more.
But can somebody explain how I can actually opt-in for the Copy trait when declaring a closure?
steveklabnik commentedon Jan 4, 2016
Triage: closures aren't copyable again, but I am not sure if they're intended to be or not. @rust-lang/lang?
bluss commentedon Jan 4, 2016
They were deliberately made non-copy in issue #19817
huonw commentedon Jan 5, 2016
There's a few possible ways to have duplicatable closures (all aren't great, unfortunately):
&
reference instead of the closure itself (&F
implementsFn
whenF
itself does), which implementsCopy
Rc<F>
(possibly a trait object), similar to the above, but this can be stored/returned (only implementsClone
fn foo<F, G>(f: F) where F: Fn() -> G, G: Fn(...) -> ...
instead offn foo<F>(f: F) where F: Fn(...) -> ...
, where theF
closure creates new instances of the actual closure of interest (G
), effectively behaving as theclone
function. I suspect this often works as justfoo(|| |actual| closure)
, i.e. just add||
at the start of the closure.These have various downsides e.g. the first two only work for
Fn
(notFnMut
orFnOnce
), the first cannot be returned from functions/stored inside return values, the second doesn't integrate with generics quite as well as others, and the third is rather ugly.steveklabnik commentedon Jan 5, 2016
Thanks @bluss !