🎈
快乐笔记 HappyNotes-综合基础科学学习笔记集
  • 前言
  • 计算机
    • 语言
      • 汇编
        • 基础
          • 概念
          • 指令集
        • x86
        • amd64
      • C
      • C++
      • Rust
        • 基础
          • 语法
            • 函数
            • 字面量
            • 流程控制
            • 闭包
            • 静态变量
            • 迭代器
            • 运算符
            • Result枚举
            • Option枚举
            • Page 17
            • Page 16
            • Page 9
          • 指针
          • 进程
          • 内存
          • 指针
          • 网络
          • 数学运算
          • 环境与配置
          • 工程组织管理
          • WASM
          • IO
          • FFI
            • 基础
            • 库
            • cbindgen
        • 标准库
      • Java
        • JDK
          • JUC
            • 基础
              • 基础
              • 相关链接
            • 集合
              • ConcurrentHashMap
              • 基础
      • Solidity
        • 基础
          • EIP标准
          • 可升级合约
          • 变量
          • 存储位置
          • 常量
        • 框架
          • OpenZeppelin
            • 基础
            • API
            • 常用操作
            • Page 19
          • UniSwap
          • PancakeSwap
        • 工具链
          • Hardhat
          • Truffle
        • IDE
          • Remix
      • Go
      • Javascript
      • Typrscript
      • Zig
      • Python
      • SQL
      • Lisp
      • 脚本
        • 正则表达式
        • bat
        • markdown
        • shell
        • toml
        • yaml
    • OS
      • 基础
        • 空间
      • Linux
        • 基础
        • 内核
        • 命名空间
        • 文件系统
        • 命令
        • 进程系统
        • 工具
        • 三方版本
          • Kali
            • metasploit
          • Ubantu
      • MacOS
      • Windows
      • 工具
        • make
        • netcat
    • 存储
      • 搜索引擎
        • OpenSearch
        • ZincSearch
      • 存储系统
        • IPFS
        • Etcd
      • 基础
      • 数据库
        • 工具
        • 区块链
        • 非关系型
        • 关系型
        • 列型
        • 图型
        • 数据仓库
    • 前端
    • 移动端
      • Android
      • IOS
    • 区块链
      • 原理
      • Page 4
      • 公链架构
        • Ethereum
          • 基础
            • 交易
            • Page 15
            • Page 14
            • Page 13
            • Page 12
          • ETH2.0
            • 升级路线
            • 名词解释
            • Page 11
            • Page 10
          • 节点
          • 链桥
          • Page 8
          • Page 7
          • Page 6
        • Page 5
      • 存储架构
      • L2架构
      • Defi
      • 工具
      • Page 2
      • Page 1
      • Page
      • Page 3
    • 文件系统
      • 基础
      • NTFS
    • 系统架构
      • cex-架构
      • 仓储系统
    • 中间件
      • Web3
        • Moralis
      • 搜索
        • Algolia
      • AI
      • Consul
      • FFmpeg
      • MeiliSearch
      • 运维
        • K8s
          • 基础
          • 命令
    • 协议
      • RTMP
    • 密码学
    • 数据结构
    • 算法
    • 编译器
      • LLVM
    • 服务器
      • JBoss
      • Jetty
      • Nginx
      • Tomcat
      • Underow
    • 名词解释
    • 硬件
    • 信息论
    • 网络
    • 容器
    • AI
    • 内存
    • 安全
    • 分布式
    • 工具
      • Git
  • 基础科学
    • 电子信息
      • 模拟电路
      • 数字电路
      • 信号
    • 物理
    • 化学
    • 机械
      • 汽车
      • 发动机
      • 发射装置
      • 飞行器
      • 火箭
    • 金融
      • 基础
        • 劣后与优先
        • VIE架构
      • 技术指标
        • 斐波那契回撤
        • 蜡烛图(OHLC)
        • 贝塔系数
        • 斐波那契速度阻力扇
        • 斐波那契趋势时间
        • 斐波那契速度阻力弧
        • 斐波那契楔形
        • 斐波那契圈
        • 斐波那契时区
      • 债务理论
    • 数学
      • 基础
        • 概念
        • 规范
        • 数
        • 运算
          • 四则运算
          • 解析式
          • 幂运算
          • 因数分解
      • 代数
      • 方程
        • 二元一次方程
        • 一元二次方程
        • 分式方程
        • 不等式
        • 一次函数
        • 二次函数
        • 三元一次方程
        • 三角函数
        • 一元一次方程
        • 反比例函数
      • 概率与统计
      • 高等数学
      • 工具
    • 易经
      • 爻卦
  • 法律
    • 公司法
    • 管制刀具认定标准
    • 物权法
    • 刑法
    • 知识产权法
  • 人类语言
Powered by GitBook
On this page
  • 概述
  • 创建闭包
  • 格式
  • 合法的定义
  • 分类
  • 受限程度
  • 不同点
  • move 关键字
  • 特点
  • 注意
  • 闭包参数
  • Fn
  • FnMut
  • FnOnce
  • 案例
  • 简单案例
  • FnOnce闭包案例
  1. 计算机
  2. 语言
  3. Rust
  4. 基础
  5. 语法

闭包

概述

闭包只是定义了代码,存储代码,并不是执行。 闭包(Closure)也叫Lambda表达式或匿名函数。 不像普通函数,闭包可以对参数和返回类型进行推断,大多数时候都不需要写出来。 闭包是一种匿名类型,一旦声明,就会产生一个新的类型,但这个类型无法被其它地方使用。这个类型就像一个结构体,会包含所有捕获的变量。

创建闭包

格式

// fn 闭包
let fn = |参数列表| -> 返回类型 {代码段};
// FnMut 闭包
let mut fn = |参数列表| -> 返回类型 {代码段};
// FnOnce 闭包,move 可有可无,如果函数内发生所有权移交,也会触发
let fn = move |参数列表| -> 返回类型 {代码段};
// 无参闭包
let res = {
    // 代码段
    // 返回值
};
// 立即执行闭包
(|参数列表| -> 返回值 {代码段})(传入参数)

合法的定义

|| 42;
|x| x + 1;
|x:i32| x + 1;
|x:i32| -> i32 { x + 1 };

分类

闭包的类型 在Rust语言中,闭包是一种特殊的类型,被称为Fn、FnMut和FnOnce。这些类型用于区分闭包的捕获方式和参数类型。

Fn:表示闭包只是借用了自由变量,不会修改它们的值。这意味着,闭包可以在不拥有自由变量所有权的情况下访问它们。
FnMut:表示闭包拥有自由变量的可变引用,并且可能会修改它们的值。这意味着,闭包必须拥有自由变量的所有权,并且只能存在一个可变引用。
FnOnce:表示闭包拥有自由变量的所有权,并且只能被调用一次。这意味着,闭包必须拥有自由变量的所有权,并且只能在调用之后使用它们。

解释

Fn : 表示闭包以不可变引用的方式来捕获环境中的自由变量,同时也表示该闭包没有改变环境的能力,并且可以多次调用。对应 &self。
FnMut : 表示闭包以可变引用的方式来捕获环境中的自由变量,同时意味着该闭包有改变环境的能力,也可以多次调用。对应 &mut self。
FnOnce : 表示闭包通过转移所有权来捕获环境中的自由变量,同时意味着该闭包没有改变环境的能力,只能调用一次,因为该闭包会消耗自身。对应 self。如果你希望强制闭包获取其使用的环境值的所有权,可以在参数列表前使用 move 关键字。这个技巧在将闭包传递给新线程以便将数据移动到新线程中时最为实用。

受限程度

Fn > FnMut > FnOnce
//顺序之所以是这样,是因为:
//&T只是获取了不可变的引用权
//&mut T则可以改变 变量的值
//T更厉害了,还能拿到了变量的所有权而非借用。

不同点

它们的调用方法分别采用&self、&mut self和self,这意味着Fn对其捕获具有不可变的访问权限,FnMut获得可变的访问权限,FnOnce可以获得所有权。 Fn和FnMut类型的闭包可以执行多次,而FnOnce类型的闭包只能执行一次。

move 关键字

如果没有实现Copy,就是move语义,会发生移动。
如果实现Copy(例如:#[derive(Copy)]),则是copy语义,会发生拷贝。
值得注意的是move与闭包的类型没有关系。
带move闭包,函数外和函数内的同名变量不是同一个变量。
不带move闭包,函数外和函数内的同名变量是同一个变量。
闭包函数执行完闭包后:带move闭包,使用闭包变量会产生【error[E0382]: borrow of moved value: p】错误。
闭包函数执行完闭包后:不带move闭包,使用闭包变量,正常执行。

特点

声明时使用 || 替代 () 将输入参数括起来。
函数体定界符({})对于单个表达式是可选的,其他情况必须加上。
有能力捕获外部环境的变量。

注意

参数列表可省略类型,但必须发生调用,否则编译报错。 返回值可为空,会自动推导。

闭包参数

Fn

Fn 可以通过不可变的引用捕获变量。

fn apply<F>(f: F) where F: Fn()
{
    f();
}
// or
fn apply<F>(f: impl Fn())
{
    f();
}


fn main() {
    let name = "jiangbo";
    let say = || println!("hello: {}", name);
    apply(say);
}

FnMut

可以通过可变引用捕获。

fn apply<F>(mut f: F) where F: FnMut()
{
    f();
}
// or
fn apply<F>(mut f: impl FnMut(u64)) 
{
    f();
}

fn main() {
    let mut name = "jiangbo".to_owned();
    let say = || {
        name.push_str("44");
        println!("hello: {:?}", name);
    };
    apply(say);
}

FnOnce

fn create_fnonce() -> impl FnOnce() {
    let text = "FnOnce".to_owned();
    move || println!("This is a: {}", text)
}

fn main() {
    let fn_once = create_fnonce();
    fn_once();
}

案例

简单案例

let closure = |a: i32| -> i32 {
    println!("a={}", a);
    a
};
println!("closure return {}", closure(10));
// 或
let closure = |a: i32| -> i32 println!("a={}", a);
println!("closure return {}", closure(10));
// 或
let F = |a: i32,b:i32| -> i32 {
    println!("a={},b={}", a,b);
    a+b
};
println!("a+b={}",F(1,2))

FnOnce闭包案例

fn main(){
    let a = Box::new(23);
    let call_me = || {
        let c = a;    
    }
    call_me();
    call_me();// 报错,这个示例中,闭包call_me中发生了所有权的移交(move语义),Box指针所指向的堆内存的所有权从a移交给了c,而随着c离开包后生命周期的结束,该堆内存也被释放掉。环境中的自由变量a在被闭包执行一次之后,就失效了。
}
Previous流程控制Next静态变量

Last updated 1 year ago