Как создать функцию `FnOnce` - PullRequest
1 голос
/ 27 июня 2019

Я пытаюсь создать функцию, которая является FnOnce.

Следующий фрагмент кода не работает:

// 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() -> ());

1 Ответ

1 голос
/ 28 июня 2019

FnOnce - это характеристика для замыканий, которую можно вызывать только один раз, как правило, потому что захваченные значения перемещаются в замыкание и используются во время вызова.Например, мы можем захватить значение и переместить его как возвращаемое значение:

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());
}

Обратите внимание, что ключевое слово move не является строго обязательным.Компилятор видит, что a необходимо переместить в замыкание, чтобы вернуть его в качестве значения и удалить.

...