RUST 笔记(七)

闭包

  1. 可以保存进变量或作为参数传递给其他函数的匿名函数;
  2. 可以在一个地方创建闭包,然后在不同的上下文中执行闭包运;
  3. 不同于函数,闭包允许捕获调用者作用域中的值。
闭包的定义
  1. 以一对竖线(|)开始,在竖线中指定闭包的参数;之所以选择这个语法是因为它与 Smalltalk 和 Ruby 的闭包定义类似。
  2. 参数之后是存放闭包体的大括号 —— 如果闭包体只有一行则大括号是可以省略的。大括号之后闭包的结尾,需要用于 let 语句的分号。
闭包的类型推断和注解
  1. 闭包不要求像 fn 函数那样在参数和返回值上注明类型。
  2. 函数中需要类型注解是因为他们是暴露给用户的显式接口的一部分。但是闭包并不用于这样暴露在外的接口:他们储存在变量中并被使用,不用命名他们或暴露给库的用户调用。闭包通常很短并只与对应相对任意的场景较小的上下文中。在这些有限制的上下文中,编译器能可靠的推断参数和返回值的类型,类似于它是如何能够推断大部分变量的类型一样
带有泛型的和 Fn trait 的闭包
struct Cacher<T>
    where T: Fn(u32) -> u32
{
    calculation: T,
    value: Option<u32>,
}
  1. 在结构体中实现闭包:指定类型,实现 Fn trait bound
  2. Fn 系列 trait 由标准库提供。所有的闭包都实现了 trait Fn、FnMut 或 FnOnce 中的一个,用来捕获环境;
闭包捕获环境

当闭包从环境中捕获一个值,闭包会在闭包体中储存这个值以供使用。这会使用内存并产生额外的开销

  1. FnOnce:不能多次获取相同变量的所有权的事实,它只能被调用一次。
  2. FnMut:获取可变的借用值所以可以改变其环境;
  3. Fn: 从其环境获取不可变的借用值

注:

  1. 由于所有闭包都可以被调用至少一次,所以所有闭包都实现了 FnOnce 。
  2. 强制闭包获取其使用的环境值的所有权,可以在参数列表前使用 move 关键字:let equal_to_x = move |z| z == x;//x 被移动进了闭包

迭代器

let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter {
    println!("Got: {}", val);
}
  1. 迭代器是 惰性的(lazy),这意味着直到调用方法消费迭代器之前它都不会有效果;
  2. next 是 Iterator 实现者被要求定义的唯一方法;
  3. 每一个 next 调用都会从迭代器中消费一个项,这些调用 next 方法的方法被称为消费适配器
迭代器适配器

将当前迭代器变为不同类型的迭代器。可以链式调用多个迭代器适配器。不过因为所有的迭代器都是惰性的,必须调用一个消费适配器方法以便获取迭代器适配器调用的结果。
如:map,但必须调用collect()来消费迭代器:这个方法消费迭代器并将结果收集到一个数据结构中。

let v1: Vec<i32> = vec![1, 2, 3];

let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();

assert_eq!(v2, vec![2, 3, 4]);

使用for写法和使用迭代器写法

  // 使用for
   let mut results = Vec::new();
   for line in contents.lines() {
     if line.contains(query) {
      results.push(line);
     }
   }

  // 使用闭包迭代器
  contents.lines().filter(|line| line.contains(query)).collect()
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值