Rust语言——迭代器和闭包
-
闭包
可以捕获其所在环境的匿名函数, 闭包是一个函数,该函数的定义可以赋给一个变量
例子—生成自定义运动计划的程序
目标:不让用户发生不必要的等待
fn main(){ //创建闭包 let expensive_closure = |num1, num2|{ num1+num2 }; let b = expensive_closure(11, 12);//调用闭包 println!("{}", b);//23 }
闭包不要求标注参数和返回值的类型,可以自行推断,当然也可以手动标出
fn main(){ let expensive_closure = |num1, num2|{ num1+num2 }; let b = expensive_closure(11, 12);//第一个调用已经确定了闭包的参数和返回值类型,并且不能被改变 let c = expensive_closure(11.0, 12.0);//报错,因为已经推断出了i32, i32 }
解决避免多次执行一个耗时函数我们可以使用闭包并配合struct,struct持有闭包及其调用结果
struct Cacher<T> where T:Fn(u32)->u32 { calculation:T, value:Option<u32>, } impl<T> Cacher<T> where T:Fn(u32)->u32{//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 }, } } }
闭包可以捕获与闭包处在相同环境的变量,函数不可以
move关键字可以强制闭包取得它所使用的环境值的所有权
fn main(){ let a = 2; let test1 = |number|{number}; let b = test1(a);//成功捕获到环境变量a println!("{}", a);//此时a的所有权并没有被闭包夺走 }
fn main(){ let x = vec![1, 2, 3]; let equal_to_x = move |z| z==x; println!("{:#?}", x);//move将环境变量的所有权占有了 let y = vec![1, 2, 3]; assert!(equal_to_x(y)) }
-
迭代器
遍历每一个元素 : .iter()
iterator trait仅要求实现一个方法:next
next:用一次往下走一项
每次返回迭代器的一项
返回结果包裹在Some里
迭代结束,返回None
可以直接在迭代器上调用next方法
fn main(){ let vec = vec![1, 2, 3]; let mut v1_iter = vec.iter(); assert_eq!(v1_iter.next(), Some(&1)); assert_eq!(v1_iter.next(), Some(&2)); assert_eq!(v1_iter.next(), Some(&3)); assert_eq!(v1_iter.next(), None); }
sum()函数
fn main(){ let vec = vec![1, 2, 3]; let v1_iter = vec.iter(); let total:i32 = v1_iter.sum(); println!("sum = {}", total);//6 }
map()方法将一个迭代器变成另一个迭代器
fn main(){ let vec = vec![1, 2, 3]; let v1_iter = vec.iter(); let iter_map:Vec<_> = v1_iter.map(|x|x+1).collect(); println!("{:#?}", iter_map);//2, 3, 4 }
filter方法:
接收一个闭包,这个闭包在遍历迭代器每个元素时,返回bool类型
如果闭包返回true:当前元素将会包含在filter产生的迭代器中,若false则不会包含在filter产生的迭代器中
下一篇:
cp 命令 复制文件及目录