I have code which (greatly simplified) boiled down to: ``` fn attempt_1<T>(action: &fn() -> T) -> T { action() }
fn call_attempt_1() -> ~str { let mut index = 0; let string = ~"str"; do attempt_1 { // No problem here. We have a stack closure. index += 1; // Error: cannot move out of captured outer variable // Makes sense. Compiler can't tell the action will only be invoked // once. string } } ``` So, I heard there are things called `once fn`, which seem to be what I need. Even though the compiler warned me away from them, I thought I'd give them a try in the spirit of investigation: ``` fn attempt_2<T>(action: &once fn() -> T) -> T { action() } fn call_attempt_2() -> ~str { let mut index = 0; let string = ~"str"; do attempt_2 { // Error: cannot assign to immutable captured outer variable in a heap closure // It seems that `&once fn` is a _heap_ closure? Makes no sense... It // would have made sense if it was an `~once fn`, but there's no way // that `action_2` should be able to store somewhere a reference to an // `&once fn`, so a stack closure should be fine! index += 1; string } } ``` So, obviously `once fn` doesn't do what I expected it to do, which is to simply assert "this fn is only called once". It seems it does that but also carries some extra baggage of also saying "force me to be a heap closure". It isn't clear to me _why_ these two should be conflated - after all, one could just say `~once fn` if one wanted a heap closure. Can someone enlighten me on this? At any rate, I then resorted to: ``` fn attempt_2<T>(action: &fn() -> T) -> T { action() } fn call_attempt_2() -> ~str { let mut index = 0; let string = ~"str"; let string_cell = Cell::new(string); do attempt_1 { // No problem here. We have a stack closure. index += 1; // Dynamic assertion that the action is only invoked once. Costs in // both extra ugly source code lines and in run-time overhead. string_cell.take() } } ``` So, this works, but boy is it ugly, not to mention inefficient Can someone suggest a better way to achieve this, and shed some light on the status of the `once fn` construct in general? Thanks, Oren Ben-Kiki
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev