Rust编程语言-13-函数式编程(闭包和迭代器)

Rust语言的设计吸收了许多其它语言的优秀设计,比如函数式编程和闭包

闭包closure

能捕获环境参数的匿名函数

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  ;

Rust中定义了Fn, FnMut, FnOnce几种Trait

struct Cacher where T: Fn(u32) -> u32,
{
    calculation: T,
    value: Option,
}

impl Cacher
where
    T: Fn(u32) -> u32,
{
    fn new(calculation: T) -> Cacher {
        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
            }
        }
    }
}
  • FnOnce:Once代表了move,变量只能被移动一次,不能被多次夺取所有权
  • FnMut:可变借用,可以多次
  • Fn:不可变借用
fn main() {
    let x = vec![1, 2, 3];

    let equal_to_x = move |z| z == x;

    println!("can't use x here: {:?}", x);

    let y = vec![1, 2, 3];

    assert!(equal_to_x(y));
}
  • move: 强制move,一般用做把变量引入线程中

Iterator

Rust中Iterator是懒加载的,就是在consume之前实际上什么都没有执行,如下代码,因为没有consume,实际上什么都没做(与Java的lambda表达式类似)

fn main() {
    let v1 = vec![1, 2, 3];
    let v1_iter = v1.iter();
}

  • into_iter() vs iter()
  • iter_mut() vs iter()

#![allow(unused)]
fn main() {
pub trait Iterator {
    type Item;

    fn next(&mut self) -> Option;

    // methods with default implementations elided
}
}
struct Counter {
    count: u32,
}

impl Counter {
    fn new() -> Counter {
        Counter { count: 0 }
    }
}

impl Iterator for Counter {
    type Item = u32;

    fn next(&mut self) -> Option {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn calling_next_directly() {
        let mut counter = Counter::new();

        assert_eq!(counter.next(), Some(1));
        assert_eq!(counter.next(), Some(2));
        assert_eq!(counter.next(), Some(3));
        assert_eq!(counter.next(), Some(4));
        assert_eq!(counter.next(), Some(5));
        assert_eq!(counter.next(), None);
    }

    #[test]
    fn using_other_iterator_trait_methods() {
        let sum: u32 = Counter::new()
            .zip(Counter::new().skip(1))
            .map(|(a, b)| a * b)
            .filter(|x| x % 3 == 0)
            .sum();
        assert_eq!(18, sum);
    }
}

你可能感兴趣的:(Rust编程语言-13-函数式编程(闭包和迭代器))