走进 Rust:闭包

Rust About 1,857 words

定义

|num|中的num是传入参数,多个参数可以是|param1, param2|。大括号}前一行num是闭包的返回值。let expensive_closure是这个闭包的引用(就是这个变量是一个匿名函数),不是闭包的返回值。

let expensive_closure = |num| {
    println!("calculating slowly...");
    thread::sleep(Duration::from_secs(2));
    num
};

类型推断

闭包标注类型

let expensive_closure = |num: u32| -> u32 {
    println!("calculating slowly...");
    thread::sleep(Duration::from_secs(2));
    num
};

闭包语法类似于函数语法。

  • 第一行展示了一个函数定义。
  • 第二行展示了一个完整标注的闭包定义。
  • 第三行闭包定义中省略了类型注解。
  • 第四行去掉了可选的大括号,因为闭包体只有一行。
fn  add_one_v1   (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x|             { x + 1 };
let add_one_v4 = |x|               x + 1  ;

闭包会捕获其环境

闭包中可以使用x变量。

fn main() {
    let x = 4;

    let equal_to_x = |z| z == x;

    println!("{:?}", x);

    let y = 4;

    assert!(equal_to_x(y));
}

而在函数中,则无法使用x变量。

fn main() {
    let x = 4;

    fn equal_to_x(z: i32) -> bool { z == x }

    let y = 4;

    assert!(equal_to_x(y));
}

// 无法通过编译

error[E0434]: can't capture dynamic environment in a fn item; use the || { ...
} closure form instead
 --> src/main.rs
  |
4 |     fn equal_to_x(z: i32) -> bool { z == x }
  |                                          ^

带有泛型和 Fn 的闭包

所有的闭包都实现了 trait Fn

结构体Cacher有一个泛型T的字段calculation

闭包T有一个u32的传入参数并返回一个u32

struct Cacher<T>
    where T: Fn(u32) -> u32
{
    calculation: T,
    value: Option<u32>,
}
impl<T> Cacher<T>
    where T: Fn(u32) -> u32
{
    fn new(calculation: T) -> Cacher<T> {
        Cacher {
            calculation,
            value: None,
        }
    }

    fn value(&mut self, arg: u32) -> u32 {
        match self.value {
            Some(v) => v,
            None => {
                let v = (self.calculation)(arg);
                self.value = Some(v);
                v
            },
        }
    }
}
Views: 3,134 · Posted: 2020-07-24

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh