Читаем Rust by Example полностью

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

<p id="see_also_25"><strong><a l:href="#see_also_25">See also:</a></strong></p>

A thorough analysis, Fn, FnMut, and FnOnce

<p id="input_functions"><strong><a l:href="#input_functions">Input functions</a></strong></p>

Since closures may be used as arguments, you might wonder if the same can be said about functions. And indeed they can! If you declare a function that takes a closure as parameter, then any function that satisfies the trait bound of that closure can be passed as a parameter.

// Define a function which takes a generic `F` argument

// bounded by `Fn`, and calls it

fn call_me(f: F) {

f();

}

// Define a wrapper function satisfying the `Fn` bound

fn function() {

println!("I'm a function!");

}

fn main() {

// Define a closure satisfying the `Fn` bound

let closure = || println!("I'm a closure!");

call_me(closure);

call_me(function);

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

As an additional note, the Fn, FnMut, and FnOnce traits dictate how a closure captures variables from the enclosing scope.

<p id="see_also_26"><strong><a l:href="#see_also_26">See also:</a></strong></p>

Fn, FnMut, and FnOnce

<p id="as_output_parameters"><strong><a l:href="#as_output_parameters">As output parameters</a></strong></p>

Closures as input parameters are possible, so returning closures as output parameters should also be possible. However, anonymous closure types are, by definition, unknown, so we have to use impl Trait to return them.

The valid traits for returning a closure are:

   • Fn

   • FnMut

   • FnOnce

Beyond this, the move keyword must be used, which signals that all captures occur by value. This is required because any captures by reference would be dropped as soon as the function exited, leaving invalid references in the closure.

fn create_fn() -> impl Fn() {

let text = "Fn".to_owned();

move || println!("This is a: {}", text)

}

fn create_fnmut() -> impl FnMut() {

let text = "FnMut".to_owned();

move || println!("This is a: {}", text)

}

fn create_fnonce() -> impl FnOnce() {

let text = "FnOnce".to_owned();

move || println!("This is a: {}", text)

}

fn main() {

let fn_plain = create_fn();

let mut fn_mut = create_fnmut();

let fn_once = create_fnonce();

fn_plain();

fn_mut();

fn_once();

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

Перейти на страницу:

Похожие книги