fcracker79
fcracker79

Reputation: 1218

How to create a `FnOnce` function

I am trying to create a function that is only a FnOnce.

The following snippet of code do not work:

// Attempt 1
//  Error doesn't have a size known at compile-time
let f: FnOnce() -> () = || println!("Hello");

// Attempt 2
fn g<T: FnOnce() -> ()>(c: T) -> (FnOnce() -> ()) {
    c
}
// Error: doesn't have a size known at compile-time
let f = g(|| println!("Hello"));

// Attempt 3
// Error: cast to unsized type
let f = (|| println!("Hello")) as (FnOnce() -> ());

Upvotes: 2

Views: 584

Answers (1)

starblue
starblue

Reputation: 56762

FnOnce is a trait for closures which can only be called once, typically because the captured values are moved into the closure, and they are consumed during the call. For example, we can capture a value and move it out as a return value:

fn delay<A: 'static>(a: A) -> Box<dyn FnOnce() -> A> {
    Box::new(move || a)
}

fn main() {
    let a = "hello".to_string();
    let f = delay(a);
    println!("{}", f());
}

Note that the move keyword is not strictly necessary. The compiler sees that a needs to be moved into the closure, in order to be returned as a value and moved out.

Upvotes: 1

Related Questions