Rust 学习笔记:闭包

第九章 rust闭包详解 闭包在rust中非常常见,在前面多线程开发章节中我相信大家已经见识到,所以这里有必要对其进行详解介绍,Rust中的闭包和C++中的lambda表达式很像,它是一个可以保存在一个变量、或者作为一个参数传递给其它函数的匿名函数。与普通函数的不同之处在于,它可以捕获所在作用域中的值。 阅读详情

Rust 学习笔记:闭包

Rust 的闭包是匿名函数,可以保存在变量中,也可以作为参数传递给其他函数。

可以在一个地方创建闭包,然后在其他地方调用闭包,以便在不同的上下文中对其进行计算。

与函数不同,闭包可以从定义它们的作用域捕获值。

用闭包捕获环境

实现一个赠送衬衫的程序。如果选择免费衬衫的人有他们最喜欢的颜色,他们就会得到那种颜色的衬衫。如果这个人没有指定最喜欢的颜色,他们就会得到公司目前最常用的颜色。

示例:

#[derive(Debug, PartialEq, Copy, Clone)]
enum ShirtColor {
    Red,
    Blue,
}

struct Inventory {
    shirts: Vec<ShirtColor>,
}

impl Inventory {
    fn giveaway(&self, user_preference: Option<ShirtColor>) -> ShirtColor {
        user_preference.unwrap_or_else(|| self.most_stocked())
    }

    fn most_stocked(&self) -> ShirtColor {
        let mut num_red = 0;
        let mut num_blue = 0;

        for color in &self.shirts {
            match color {
                ShirtColor::Red => num_red += 1,
                ShirtColor::Blue => num_blue += 1,
            }
        }
        if num_red > num_blue {
            ShirtColor::Red
        } else {
            ShirtColor::Blue
        }
    }
}

fn main() {
    let store = Inventory {
        shirts: vec![ShirtColor::Blue, ShirtColor::Red, ShirtColor::Blue],
    };

    let user_pref1 = Some(ShirtColor::Red);
    let giveaway1 = store.giveaway(user_pref1);
    println!(
        "The user with preference {:?} gets {:?}",
        user_pref1, giveaway1
    );

    let user_pref2 = None;
    let giveaway2 = store.giveaway(user_pref2);
    println!(
        "The user with preference {:?} gets {:?}",
        user_pref2, giveaway2
    );
}

在 giveaway 方法中,我们将用户偏好作为 Option<ShirtColor> 类型的参数获取,并在 user_preference 上调用 unwrap_or_else 方法。Option<T> 上的 unwrap_or_else 方法由标准库定义。它接受一个参数:一个没有任何参数的闭包,返回一个值T(与存储在 Option<T> 的 Some 变体中的类型相同,在本例中为 ShirtColor)。如果 Option<T> 是 Some 变量,则 unwrap_or_else 返回 Some 中的值。如果 Option<T> 是 None 变量,则 unwrap_or_else 调用闭包并返回闭包返回的值。

我们指定闭包表达式 || self.most_stocked() 作为 unwrap_or_else 的参数。这是一个本身不接受参数的闭包(如果闭包有参数,它们将出现在两个竖条之间)。闭包的主体调用 self.most_stocked()。

闭包捕获对 self Inventory 实例的不可变引用,并将其与我们指定的代码一起传递给 unwrap_or_else 方法。一般函数是做不到这一点的。

闭包类型推断和注释

闭包通常不需要像 fn 函数那样注释参数的类型或返回值。

闭包通常很短,在这些有限的上下文中,编译器可以推断参数的类型和返回类型。

在极少数情况下,编译器也需要闭包类型注释。

为闭包注释类型类似于下面的例子。我们定义了一个闭包并将其存储在一个变量中。

    let expensive_closure = |num: u32| -> u32 {
        println!("calculating slowly...");
        thread::sleep(Duration::from_secs(2));
        num
    };

添加了类型注释后,闭包的语法看起来更类似于函数的语法。

以下四种定义的行为都是一致的:

// 函数定义
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  ;

对于闭包定义,编译器将为它们的每个形参及其返回值推断出一个具体类型。因为没有类型注解,我们可以用任何类型调用闭包。

示例:

    let example_closure = |x| x;

    let s = example_closure(String::from("hello"));
    let n = example_closure(5);

程序报错:

在这里插入图片描述

当我们第一次用 String 值调用 example_closure 时,编译器推断出 x 的类型和闭包的返回类型为 String。然后,这些类型被锁定在 example_closure 中的闭包中,当我们下一次尝试对相同的闭包使用不同的类型时,我们会得到一个类型错误。

捕获引用或移动所有权

闭包可以通过三种方式从其环境中获取值:不可变借用、可变借用和获取所有权。闭包将根据函数体如何处理捕获的值来决定使用哪一个。

示例 1:

fn main() {
    let list = vec![1, 2, 3];
    println!("Before defining closure: {list:?}");

    let only_borrows = || println!("From closure: {list:?}");

    println!("Before calling closure: {list:?}");
    only_borrows();
    println!("After calling closure: {list:?}");
}

定义了一个闭包 only_borrows,它捕获了一个指向名为 list 的 vector 的不可变引用,因为它只需要一个不可变引用就可以输出值。

这个例子还说明了变量可以绑定到闭包定义,稍后我们可以通过使用变量名和括号调用闭包,就好像变量名是函数名一样。

因为我们可以同时对 list 有多个不可变引用,所以在闭包定义之前、在闭包定义之后、在闭包被调用之前和在闭包被调用之后,都可以访问 list。这段代码编译、运行和输出:

在这里插入图片描述

示例 2:

fn main() {
    let mut list = vec![1, 2, 3];
    println!("Before defining closure: {list:?}");

    let mut borrows_mutably = || list.push(7);

    borrows_mutably();
    println!("After calling closure: {list:?}");
}

我们修改闭包体,使其向列表向量添加一个元素。

当定义 borrows_mutable 时,它捕获一个对 list 的可变引用。在闭包定义和闭包调用之间,不允许使用不可变借用来打印,因为当存在可变借用时不允许使用其他借用。

如果想强制闭包获得它在环境中使用的值的所有权,可以在参数列表之前使用 move 关键字。

当向新线程传递闭包以移动数据以使其归新线程所有时,此技术非常有用。

示例 3:

use std::thread;

fn main() {
    let list = vec![1, 2, 3];
    println!("Before defining closure: {list:?}");

    thread::spawn(move || println!("From thread: {list:?}"))
        .join()
        .unwrap();
}

我们生成一个新线程,给线程一个闭包作为参数运行。尽管闭包体只需要一个不可变引用就能完成打印,但我们需要通过在闭包定义的开头放置 move 关键字来指定应该将列表移动到闭包中。

新线程可能在主线程的其余部分完成之前完成,或者主线程可能先完成。如果主线程保持 list 的所有权,但在新线程结束并删除list之前结束,则线程中的不可变引用将无效。因此,编译器要求将 list 移到给新线程的闭包中,这样引用才有效。

将捕获的值移出闭包和 Fn Traits

一旦闭包从定义闭包的环境中捕获了引用或捕获了值的所有权,闭包体中的代码将定义在稍后求值闭包时对引用或值的处理。

闭包体可以执行以下任何操作:将捕获的值移出闭包,改变捕获的值,既不移动也不改变值,或者从环境开始不捕获任何值。

闭包从环境中捕获和处理值的方式会影响闭包实现的 trait,而 trait 就是函数和结构如何指定它们可以使用的闭包类型。闭包将以一种附加的方式自动实现一个、两个或所有这三个 Fn trait,具体取决于闭包的主体如何处理这些值:

  1. FnOnce:应用于可以调用一次的闭包。所有闭包都至少实现了这个 trait,因为所有闭包都可以被调用。将捕获值移出其体的闭包只会实现 FnOnce,而不会实现其他 Fn trait,因为它只能被调用一次。
  2. FnMut:应用于闭包,闭包不会将捕获的值移出其主体,但可能会改变捕获的值。这些闭包可以被多次调用。
  3. Fn:适用于不会将捕获值移出其主体且不会改变捕获值的闭包,以及不从其环境中捕获任何值的闭包。这些闭包可以被多次调用而不会改变它们的环境,这在并发调用多次闭包的情况下非常重要。

让我们看一下 Option<T> 的 unwrap_or_else 方法的定义:

impl<T> Option<T> {
    pub fn unwrap_or_else<F>(self, f: F) -> T
    where
        F: FnOnce() -> T
    {
        match self {
            Some(x) => x,
            None => f(),
        }
    }
}

T 是泛型类型,表示 Option 的某些变体中的值的类型,也是 unwrap_or_else 函数的返回类型。

unwrap_or_else 函数具有额外的泛型类型参数 F,它是我们在调用 unwrap_or_else 时提供的闭包。

在泛型类型 F 上指定的 trait 绑定是 FnOnce() -> T,这意味着 F 必须能够被调用一次,不接受参数,并返回一个 T。在函数体中,如果 Option 是 Some,则不会调用 f。如果 Option 为 None,则 f 将被调用一次。因为所有闭包都实现了 FnOnce,所以 unwrap_or_else 函数接受所有三种闭包。

注意:如果我们想要做的事情不需要从环境中捕获值,我们可以使用函数名而不是闭包。
例如,如果 Option<Vec<T>> 值为 None,则可以调用 unwrap_or_else(Vec::new) 来获得一个新的空 vector。编译器自动实现任何一个适用于函数定义的 Fn traits。

现在让我们看一下在切片上定义的标准库方法 sort_by_key,看看它与 unwrap_or_else 有什么不同,以及为什么 sort_by_key 使用 FnMut 而不是 FnOnce 作为 trait 绑定。闭包以引用的形式获得一个参数,并返回排序后的结果。

在下面的示例中,我们有一个矩形实例列表,我们使用 sort_by_key 按它们的 width 属性从低到高排序:

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let mut list = [
        Rectangle { width: 10, height: 1 },
        Rectangle { width: 3, height: 5 },
        Rectangle { width: 7, height: 12 },
    ];

    list.sort_by_key(|r| r.width);
    println!("{list:#?}");
}

运行结果:

在这里插入图片描述

sort_by_key 被定义为接受 FnMut 闭包的原因是,它多次调用闭包:对片中的每个项调用一次。闭包 |r| r.width 不会捕获、改变或从其环境中移出任何东西。

相反,下面的代码展示了一个闭包示例,它只实现了 FnOnce trait,因为它将一个值移出了环境。编译器不允许我们使用 sort_by_key 闭包。

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let mut list = [
        Rectangle { width: 10, height: 1 },
        Rectangle { width: 3, height: 5 },
        Rectangle { width: 7, height: 12 },
    ];

    let mut sort_operations = vec![];
    let value = String::from("closure called");

    list.sort_by_key(|r| {
        sort_operations.push(value);
        r.width
    });
    println!("{list:#?}");
}

这段代码试图通过将一个字符串从闭包的环境压入数组来完成计数。闭包捕获 value,然后通过将 value 的所有权转移给 sort_operations 数组,将 value 移出闭包。这个闭包只可以被调用一次,尝试第二次调用它将不起作用,因为 value 已经没有对字符串的所有权了。因此,这个闭包只实现了 FnOnce。当我们尝试编译这段代码时,会得到这样的错误:不能将值移出闭包,因为闭包必须实现 FnMut。

在这里插入图片描述

错误指向闭包体中将值移出环境的行。要解决这个问题,我们需要更改闭包体,使其不会将值移出环境。在环境中保留一个计数器并在闭包体中增加其值是计算闭包调用次数的更直接的方法。

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let mut list = [
        Rectangle { width: 10, height: 1 },
        Rectangle { width: 3, height: 5 },
        Rectangle { width: 7, height: 12 },
    ];

    let mut num_sort_operations = 0;
    list.sort_by_key(|r| {
        num_sort_operations += 1;
        r.width
    });
    println!("{list:#?}, sorted in {num_sort_operations} operations");
}

修改后的闭包可以与 sort_by_key 一起工作,因为它只捕获对 num_sort_operations 计数器的可变引用,因此可以多次调用。

在定义或使用使用闭包的函数或类型时,Fn Traits 非常重要。在下一节中,我们将讨论迭代器,许多迭代器方法都接受闭包参数。

【Rust闭包】rust语言闭包函数原理用法汇总与应用实战 闭包(Closure)是 Rust 中一个强大且灵活的特性,它允许你捕获环境中的变量并在稍后执行。Rust 的闭包设计既高效又安全,是函数式编程风格的重要组成部分。 Rust 的 闭包(closures)是可以保存进变量或作为参数传递给其他函数的匿名函数。 可以在一个地方创建闭包,然后在不同的上下文中执行闭包运算。 不同于函数,闭包允许捕获调用者作用域中的值。 阅读详情

相关推荐

Zynq UltraScale+ MPSoC-AMP(linux+裸机)

接着 Zynq UltraScale+ MPSoC-双核裸机AMP继续 平台工具:zcu106,vitis2020.2,petalinux2019.2 文章目录1.cpu1跑裸机2.cpu0跑linux2.1petalinux设置2.2 app3.生成BOOT.bin4.zcu106测试 1.cpu1跑裸机 参照Zynq UltraScale+ MPSoC-双核裸机AMP建立的工程进行修改。BSP中stdin与out修改为uart1,uart1给裸机用,uart0给linux用。 ddr空间裸机与linu

zhuxl24的博客 5195

【Rust 基础篇】Rust 闭包

闭包在 Rust 中使用||符号来定义,类似于匿名函数。闭包可以捕获其环境中的变量,并在需要时进行调用。println!在上述示例中,我们定义了一个名为add的闭包,它接受两个参数a和b,并返回它们的和。我们通过add(2, 3)调用闭包,并将结果打印出来。闭包使用||符号来定义参数列表,并使用代码块来定义闭包的主体。本篇博客详细介绍了 Rust 中的闭包,包括闭包的定义、语法、捕获变量的方式以及常见的使用场景。

繁依Fanyi的博客 2042

Zynq/ZynqMP PL端以太网实战:手把手教你用GMII to RGMII IP和EMIO打通网络(附KSZ9031 PHY驱动修改)

本文详细介绍了在Zynq/ZynqMP平台上使用GMII to RGMII IP核和EMIO接口实现PL端以太网通信的全栈开发流程,特别针对KSZ9031 PHY芯片提供了定制化驱动修改方案。内容涵盖硬件设计、Vivado配置、裸机驱动开发、Linux系统集成及实战调试技巧,帮助开发者高效解决工业控制和边缘计算中的以太网连接问题。

weixin_30642561的博客 582

rust闭包(Closure)

闭包在现代化的编程语言中普遍存在。闭包是一种匿名函数,它可以赋值给变量也可以作为参数传递给其它函数,不同于函数的是,它允许捕获调用者作用域中的值。Rust 闭包在形式上借鉴了 Smalltalk 和 Ruby 语言,与函数最大的不同就是它的参数是通过 |parm1| 的形式进行声明,如果是多个参数就 |param1, param2,…|, 下面给出闭包的形式定义: 如果只有一个返回表达式的话,定义可以简化为: 闭包可以接受0个或者多个参数,写在||里面; 闭包体中是实际执行的代码; 闭包可以捕获任何它周围

zy010101博客 2175

树莓派CM4 PCIe扩展方案与ASM1184e芯片应用

PCIe(Peripheral Component Interconnect Express)是计算机硬件中重要的高速串行总线标准,广泛应用于存储、网络等设备连接。其核心原理是通过差分信号实现高带宽传输,PCIe Gen2 x1的理论带宽可达5Gbps。在嵌入式开发中,PCIe扩展技术能有效解决单板计算机接口不足的问题,特别适合树莓派等微型平台。ASMedia ASM1184e作为PCIe交换芯片,可将单个接口扩展为多个,支持热插拔且免驱动,极大提升了工程灵活性。通过PCIe交换机方案,开发者能在树莓派CM

weixin_42602368的博客 421

QTableView为例:Qt模型视图委托(MVD)(Model-View-Delegate)

QT中的MVD(模型-视图-委托)模式是一种类似于MVC的设计模式,将数据、界面和交互逻辑分离。模型负责数据管理,视图负责显示界面,而委托则嵌入在视图中处理数据的显示和编辑。QT提供了多种视图组件(如QListView、QTreeView、QTableView)和模型类(如QStandardItemModel、QAbstractItemModel),支持数据的多样化呈现。委托(Delegate)通过定制显示和编辑行为增强了视图的灵活性。该模式适用于各类数据结构展示(列表、表格、树形),能够高效处理数据与界面

菜一头包的博客 1989

Rust 闭包

Rust的闭包类型分为三种: 1.Fn 2.FnMut 3.FnOnce 不同之处: 1.它们的调用方法分别采用&self、&mut self和self,这意味着Fn对其捕获具有不可变的访问权限,FnMut获得可变的访问权限,FnOnce可以获得所有权。 2.Fn和FnMut类型的闭包可以执行多次,而FnOnce类型的闭包只能执行一次。 move关键字: 1.如果没有实现Copy,就是move语义,会发生移动。 2.如果实现Copy,则是copy语义,会发生拷贝。 值得注意的是move与闭包

今天你emo了吗? 1940

《物联网技术》课程笔记——第二章 物联网技术架构

文章目录第二章:物联网技术架构1 物联网技术体系(C3SD)2 系统体系结构的基本概念3 物联网体系结构——信息传递视角3.1物联网感知层3.1.1 感知层要解决的问题3.1.2 感知层的形态3.1.3 节点的感知能力与控制能力3.1.4 感知层实例3.2 物联网网络层3.2.1 网络相关概念3.2.2 IPV6与IPV4相比互联网协议的升级3.2.3 计算机网络的逻辑层次3.2.4 传输网的拓扑结构3.2.4.1 举例:智能小区的三表采集系统3.2.4.2 接入层3.2.4.2 汇聚层3.2.4.2 核心

南京大学软件工程硕士在读 2503

Rust的闭包

文章目录Rust的闭包创建闭包闭包捕获当前环境中的变量闭包作为函数参数 Rust的闭包 几乎每一种比C语言高级的语言都有闭包。Rust也同样支持闭包。闭包有一个很通俗的名称:匿名函数,它有着如下优点: 创建闭包不用为函数取名,方便快捷 闭包可以捕获调用者作用域中的值 闭包可以被保存进变量或作为参数传递给其他函数 创建闭包 Rust创建闭包的语法很简单:|参数列表| -> 返回类型 {代码段}。用两个竖线将函数参数包裹起来,后面接返回值的类型,最后是用花括号包裹的代码段就可以了。如: fn main

鸿鹄之志 4130

DDR4协议规范之(一)DDR4结构和寻址

DDR4 SDRAM结构和寻址DDR4 SDRAM的封装和寻址新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 DDR4 SDRAM的封装和寻址 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习

YJFeiii的博客 3万+

STM32入门教程:智能马桶盖控制

通过编写相应的代码,您可以根据需要实现其他功能,例如座圈温度调节和液晶显示屏显示等。初始化配置 首先,使用STM32CubeMX创建一个新的工程,并选择您所使用的STM32单片机型号。智能马桶盖是一种集成了多种功能的智能家居设备,通过控制芯片来实现自动冲水、座圈加热、座圈温度调节等功能。在本教程中,我们将使用STM32系列单片机来控制智能马桶盖的各个功能。以上代码演示了如何通过STM32的GPIO控制引脚来控制智能马桶盖的冲水和座圈加热功能。写代码 接下来,我们将通过编写代码来控制智能马桶盖的各个功能。

2401_85258012的博客 657

Rust 学习笔记:高级函数和闭包

Rust 学习笔记:高级函数和闭包

ProgramNovice的博客 2093

【Bug已解决】Codex CLI 运行时出现 command not found: codex 解决方案

方案适用场景推荐指数修复 PATH 配置最常见的基础排查方向⭐⭐⭐⭐⭐检查原生二进制完整性PATH 正常但执行仍然异常⭐⭐⭐⭐统一包管理器混用多种包管理器导致混乱⭐⭐⭐⭐确认安装脚本未被跳过CI/CD 或企业策略环境⭐⭐⭐⭐排查网络下载渠道企业内网/受限网络环境⭐⭐⭐需要留意 warning 中是否涉及脚本执行失败、网络超时重试等信息,这类 warning 往往是后续问题的前兆,建议出现明显的下载/网络相关警告时就主动重新安装一次确认。Codex CLI 报。

一键难忘的博客 1万+

Rust 学习笔记:关于闭包的练习题

Rust 学习笔记:关于闭包的练习题

ProgramNovice的博客 507

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Rust学习笔记-5-基础篇:闭包

背景 本文主要是在阅读《Rust编程之道》的闭包章节后,对知识点做的相关梳理。目前接触Rust还不久,感觉《Rust编程之道》相对官方教程而言写的更深更细。但看完该书闭包这一节后,自己感觉有必要梳理一下其知识点,以加深理解。 来自示例的疑惑 fn main(){ let mut s="rush".to_string(); { let mut c=||{s+=" rust"}; c(); c(); println!("{:

uddiqpl的专栏 804

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

学习笔记十三—— 理解 Rust 闭包:从语法到 impl Fn vs Box<dyn Fn>

Trait(特质)就是 Rust 中的“能力接口”。谁实现了某个 Trait,就可以被当成“具有某种能力”的对象使用。Fn()表示能多次调用FnMut()表示可变调用FnOnce()表示调用一次概念通俗解释闭包能记住外部变量的小函数Trait能力接口,如 Fn 表示可调用impl Fn()编译期固定,快运行时多态,灵活Trait 对象抽象能力 + 虚表,运行时查找实际调用方法。

pumpkin84514的博客 1457

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Rust学习笔记_12——闭包

在Rust编程语言中,闭包(closures)是一种匿名函数,它能够捕获并存储其所在作用域内的变量,以便在稍后的某个时间点调用。在大多数情况下,你不需要显式地指定闭包的类型,因为Rust的编译器能够推断它。当闭包以移动方式捕获变量时,原始变量将不再可用,因为闭包已经接管了该变量的所有权。不可变捕获是闭包捕获变量的默认方式。当闭包以不可变方式捕获变量时,它只能读取该变量的值,而不能修改它。这种方式保证了闭包内部对变量的访问是安全的,因为闭包不会改变变量的状态。可变捕获允许闭包修改其捕获的变量的值。

LuckyLay的博客 1396

【rust中的闭包】

简而言之,闭包就是可以直接访问其外部作用域的函数内部匿名函数(有点狭隘,不过大部分如此)。如果你只想调用一次,用Fnonce,如果你想改变用FnMut,如果你想在多线程中使用且不改变用Fn.“我们都无法确定选择是否正确,只是努力把选择变得正确.”

m0_37719524的博客 1425

初学rust——Iterators、Closures、Crates.io and Pointers

学习rust的第五、六天,学习资料是官网的《The Rust Programming Language》,本笔记的内容包括第13-15章的内容 Chapter 13 Functional Language Features: Iterators and Closure 本章主要内容: Closure,function-like的结构,可以存储在变量中 Iterators,处理一系列元素的方法...

weixin_38243001的博客 544

【2025 Rust学习 --- 13 闭包:Rust的Lambda】

Rust独特的Lambda

weixin_53800025的博客 2353

【Rust自学】13.1. 闭包 Pt.1:什么是闭包、如何使用闭包

闭包是可以捕获其所在环境的匿名函数。闭包的特点有四:1.闭包是匿名函数 2.这个匿名函数可以保存为变量,或是作为参数传给另一个函数,还可以作为另外一个函数的返回值 3.可以在一个地方创建闭包,然后在另一个上下文中调用闭包来完成运算 4.闭包可以从其定义的作用域内捕获值

A Rookie in San Domenico School 1648

【Rust】——闭包

目录 🎯闭包会捕获其环境 🎯闭包类型推断和注解 🎯捕获引用或者移动所有权 🎯将捕获的值移除闭包和Fn trait

shsjssnn的博客 1160

Rust 闭包详解

Rust闭包详解:匿名函数的强大工具 闭包是Rust中的匿名函数,具有捕获环境变量的能力,可作为一等公民使用。文章详细介绍了闭包的核心概念、语法结构、变量捕获机制以及实际应用场景。闭包通过实现Fn、FnMut或FnOnce trait来管理变量捕获,支持按值或引用捕获外部变量。其灵活的类型推断和所有权语义使其在迭代器、回调函数和多线程编程中表现优异。文章还探讨了如何在结构体中存储闭包、处理生命周期问题,以及在多线程环境下安全使用闭包的技术,包括move关键字和Arc<Mutex<T>&gt

本博客分享软硬件一体化开发实战。硬件涵盖 PCB 设计、STM32 等 MCU 底层开发;软件包含 C++、Rust,Qt/QML、PyQt、Slint、TouchGFX、LVGL 各类 GUI 框架。方便软硬件开发者查阅学习。欢迎关注! 1375

Rust闭包

闭包

qq_74143285的博客 925

【Rust】——高级函数与闭包以及宏

目录 🎯函数指针 🎯返回闭包 🎯宏 🎯宏和函数的区别 🎯使用macro_rules!的声明宏用于通用元编程 🎯用于从属性生成代码的过程宏 🎯如何编写自定义derive宏 🎯类属性宏 🎯类函数宏

shsjssnn的博客 5075
上一篇: Rust 项目实战:命令行搜索工具 grep
下一篇: Rust 学习笔记:迭代器
UestcXiye
博客等级 码龄8年 9029粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值