当前位置: 首页 > article >正文

【Rust自学】13.4. 闭包 Pt.4:使用闭包捕获环境

13.4.0. 写在正文之前

Rust语言在设计过程中收到了很多语言的启发,而函数式编程对Rust产生了非常显著的影响。函数式编程通常包括通过将函数作为值传递给参数、从其他函数返回它们、将它们分配给变量以供以后执行等等。

在本章中,我们会讨论 Rust 的一些特性,这些特性与许多语言中通常称为函数式的特性相似:

  • 闭包(本文)
  • 迭代器
  • 使用闭包和迭代器改进I/O项目
  • 闭包和迭代器的性能

喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
请添加图片描述

13.4.1. 闭包可以捕获它所在的环境

闭包有一项函数所不具备的功能:闭包可以访问定义它的作用域内的变量。

看个例子:

fn main() {
	let x = 4;
	let equal_to_x = |z| z == x;
	let y = 4;
	assert!(equal_to_x(y));
}

闭包的部分在:

let equal_to_x = |z| z == x;

这样写有的人可能不太能分清===在这里的作用,换一种写法:

let equal_to_x = |z| {
	z == x;
}

也就是说这个闭包的形参是z,它会和x(也就是4,因为上文定义了x = 4)进行比较,返回布尔类型,如果相等就是true,反之则为false

这里闭包直接访问了同在一个作用域的变量x,这是函数做不到的。

但使用这个特性是有代价的,它会产生内存开销。大多数情况下我们不需要它捕获环境,更不想产生内存开销,所以函数它就不允许从环境中捕获变量,而定义和使用函数就永远不会产生这一类型的开销。

13.4.2. 闭包从所在环境捕获值的方式

闭包通过三种方法来从环境捕获值,这三种与函数获得参数的三种方法一样:

  • 取得所有权,其trait名为FnOnceOnce代表一次,因为闭包不能多次获取并消耗同一个变量,所以它只能被调用一次。
  • 可变借用,其trait名为FnMut
  • 不可变借用,其trait名为Fn

当程序员在创建闭包时,通过闭包对环境值当使用,Rust会推断出具体使用哪个trait:

  • 所有的闭包都实现了FnOnce,因为闭包都至少可以被调用一次
  • 没有移动捕获变量的实现了FnMut
  • 无需可变访问捕获变量的闭包实现了Fn

实际上这三者有包含关系:所有实现了Fn的都实现了FnMut,所有实现了FnMut的都实现了FnOnce

13.4.3. move关键字

在参数列表前使用move关键字,可以强制闭包取得它所使用的环境值的所有权。当将闭包传递给新线程以移动数据使其归新线程所有时,此方法最为有用。

看个例子:

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关键字后x的所有权就移动到了闭包的里面,后面就用不了x

13.4.4. 最佳实践

当你指定Fn trait bound之一时,首先用Fn,基于闭包内的情况,如果需要FnOnceFnMut,编译器会再告诉你。


http://www.kler.cn/a/509013.html

相关文章:

  • 信贷业务术语详解:深入理解金融领域的核心概念
  • js常用操作符
  • macOS安装的Ubuntu 20 VM虚拟机扩充磁盘的便捷方式
  • OpenWRT Conserver 共享串口服务实现
  • Linux UDP 编程详解
  • B3DM转换成XYZ
  • AI面试官
  • 深入HDFS——数据上传源码
  • wireshark上没有显示出来rtp协议如何处理
  • 群论学习笔记
  • Windows图形界面(GUI)-QT-C/C++ - Qt Table Widget详解教程
  • 【深度学习】Pytorch:在 ResNet 中加入注意力机制
  • 架构思考与实践:从通用到场景的转变
  • AI的出现,是否能替代IT从业者?
  • 如何使用Python将长图片分隔为若干张小图片
  • 数仓建模(五)选择数仓技术栈:Hive ClickHouse 其它
  • 函数(函数的概念、库函数、自定义函数、形参和实参、return语句、数组做函数参数、嵌套调用和链式访问、函数的声明和定义、static和extern)
  • Java中GUI编程和内部类的学习
  • 【SQL 中的分组查询与联合查询详解】
  • 面试经验分享-回忆版某小公司