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

Rust- 闭包

A closure in Rust is an anonymous function you can save in a variable or pass as an argument to another function. You can create the closure using a lightweight syntax and access variables from the scope in which it’s defined.

Here’s an example of a closure that increases a number by one:

let plus_one = |x: i32| x + 1;let a = 5;
println!("{}", plus_one(a)); // Outputs 6

In this example, plus_one is a closure that takes one argument x and returns x + 1.

Closures in Rust are similar to lambdas in other languages, but they have some specific behaviors and capabilities.

  • Capture Environment: Closures have the ability to capture values from the scope in which they’re defined. Here’s an example:

    let num = 5;
    let plus_num = |x: i32| x + num;
    println!("{}", plus_num(10)); // Outputs 15
    

    Here, plus_num captures the value of num from the surrounding environment.

  • Flexible Input Types: Unlike functions, closures don’t require you to annotate the types of the input parameters. However, you can if you want to, and sometimes doing so can increase clarity.

  • Three Flavors of Closures: Closures in Rust come in three forms, which differ in how they capture variables from the surrounding scope: Fn, FnMut, and FnOnce. The type is chosen by the compiler based on how the closure uses variables from the environment.

    • FnOnce consumes the variables it captures from its enclosing scope, known as the “once” because it can’t take ownership more than once.
    • FnMut can change the environment because it mutably borrows values.
    • Fn borrows values from the environment immutably.

Let’s start with an overview of each:

  1. FnOnce captures variables and moves them into the closure when it is defined. It can consume those variables when the closure is called. FnOnce closures can’t be called more than once in some contexts without duplication.

  2. FnMut can mutate and also consume variables from the environment in which it is defined.

  3. Fn borrows variables from the environment immutably.

Now, let’s have a look at some examples for each type:

// Example of FnOnce
let x = "hello".to_string();
let consume_x = move || println!("{}", x);
consume_x(); // "hello"
// consume_x(); This won't compile because `x` has been moved into the closure// Example of FnMut
let mut y = "hello".to_string();
let mut append_world = || y.push_str(" world");
append_world();
println!("{}", y); // "hello world"// Example of Fn
let z = "hello".to_string();
let print_z = || println!("{}", z);
print_z();
print_z(); // We can call this as many times as we want.

① In the first example, the closure takes ownership of x (indicated by the move keyword), so it’s a FnOnce.

② In the second example, the closure mutably borrows y, so it’s a FnMut.

③ In the third example, the closure immutably borrows z, so it’s a Fn.

Rust chooses how to capture variables on the fly without any annotation required. The move keyword is used to force the closure to take ownership of the values it uses.

Closures are a fundamental feature for many Rust idioms. They are used extensively in iterator adapters, threading, and many other situations.

fn main() {/*|| 代替 ()将输入参数括起来函数体界定符是{},对于单个表达式是可选的,其他情况必须加上。有能力捕获外部环境的变量。|参数列表| {业务逻辑}|| {业务逻辑}闭包可以赋值一个变量。*/let double = |x| {x * 2};let add = |a, b| {a + b};let x = add(2, 4);println!("{}", x);          // 6let y = double(5);println!("{}", y);          // 10let v = 3;let add2 = |x| {v + x};println!("{}", add2(4));    // 7/*闭包,可以在没有标注的情况下运行。可移动(move), 可借用(borrow), 闭包可以通过引用 &T可变引用 &mut T值 T捕获1. 闭包是一个在函数内创建立即调用的另外一个函数。2. 闭包是一个匿名函数3. 闭包虽然没有函数名,但可以把整个闭包赋值一个变量,通过该变量来完成闭包的调用4. 闭包不用声明返回值,但可以有返回值。并且使用最后一条语句的执行结果作为返回值,闭包的返回值也可以给变量。5. 闭包也称之为内联函数,可以访问外层函数里的变量。*/
}
fn main() {let add = |x, y| x + y;let result = add(3, 4);println!("{}", result); // 7receives_closure(add); // // 闭包作为参数执行结果 => 8let y = 2;receives_closure2(|x| x + y); // closure(1) => 3let y = 3;receives_closure2(|x| x + y); // closure(1) => 4let closure = returns_closure();println!("返回闭包 => {}", closure(1)); // 返回闭包 => 7let result = do1(add, 5);println!("result(1) => {}", result(1)); // result(1) => 6let result = do2(add, 5);println!("result(2) => {}", result(2)); // result(2) => 7
}fn do2<F, X, Y, Z>(f: F, x: X) -> impl Fn(Y) -> Z
whereF: Fn(X, Y) -> Z,X: Copy,
{move |y| f(x, y)
}// 参数和返回值都有闭包
fn do1<F>(f: F, x: i32) -> impl Fn(i32) -> i32
whereF: Fn(i32, i32) -> i32,
{move |y| f(x, y)
}// 返回闭包
fn returns_closure() -> impl Fn(i32) -> i32 {|x| x + 6
}// 闭包作为参数
fn receives_closure<F>(closure: F)
whereF: Fn(i32, i32) -> i32,
{let result = closure(3, 5);println!("闭包作为参数执行结果 => {}", result)
}// 闭包捕获变量
fn receives_closure2<F>(closure: F)
whereF: Fn(i32) -> i32,
{let result = closure(1);println!("closure(1) => {}", result);
}

相关文章:

Rust- 闭包

A closure in Rust is an anonymous function you can save in a variable or pass as an argument to another function. You can create the closure using a lightweight syntax and access variables from the scope in which it’s defined. Here’s an example of a clo…...

【数据挖掘torch】 基于LSTM电力系统负荷预测分析(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

「JVM」性能调优工具

「JVM」性能调优工具 一、jcmd1、jcmd 能干嘛&#xff1f;2、与JVM相关的命令3、示例 二、jmap1、jmap有什么用&#xff1f;2、jmap的命令大全3、示例 三、jps1、jps有什么用&#xff1f;2、jps命令以及示例 四、jstat1、jstat有什么用&#xff1f;2、jstat命令以及示例 五、js…...

IDEA Debug小技巧 添加减少所查看变量、查看不同线程

问题 IDEA的Debug肯定都用过。它下面显示的变量&#xff0c;有什么门道&#xff1f;可以增加变量、查看线程吗&#xff1f; 答案是&#xff1a;可以。 演示代码 代码如下&#xff1a; package cn.itcast.attempt.threadAttempt.attempt2;public class Test {public static …...

基于SpringBoot+Vue的车辆充电桩管理系统设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…...

Bean的加载方式

目录 1. 基于XML配置文件 2. 基于XML注解方式声明bean 自定义bean 第三方bean 3.注解方式声明配置类 扩展1&#xff0c;FactoryBean 扩展2,加载配置类并加载配置文件&#xff08;系统迁移) 扩展3&#xff0c;proxyBeanMethodstrue的使用 4. 使用Import注解导入要注入的bean…...

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(13)-Fiddler请求和响应断点调试

1.简介 Fiddler有个强大的功能&#xff0c;可以修改发送到服务器的数据包&#xff0c;但是修改前需要拦截&#xff0c;即设置断点。设置断点后&#xff0c;开始拦截接下来所有网页&#xff0c;直到取消断点。这个功能可以在数据包发送之前&#xff0c;修改请求参数&#xff1b…...

Android 13(T) - Media框架(1)- 总览

从事Android Media开发工作三年有余&#xff0c;刚从萌新变成菜鸟&#xff0c;一路上跌跌撞撞学习&#xff0c;看了很多零零碎碎的知识&#xff0c;为了加深对Android Media框架的理解&#xff0c;决定在这里记录下学习过程中想到的一些问题以及一些思考&#xff0c;也希望对初…...

简述vue3(ts)+antdesignvue项目框架搭建基本步骤

目录 项目简介 概念 过程简述 基本步骤 1.创建新项目 2.安装Ant Design Vue 3.配置Ant Design Vue 4.创建页面和组件 5.使用组件 6.运行项目 项目简介 概念 Vue 3&#xff08;使用TypeScript&#xff09;和Ant Design Vue项目框架搭建是指在Vue 3框架下&#xff0c;…...

webpack : 无法加载文件 C:\Program Files\nodejs\webpack.ps1

webpack : 无法加载文件 C:\Program Files\nodejs\webpack.ps1 1.问题2. 解决办法&#xff1a; 1.问题 使用webpack打包是报错如下&#xff1a; webpack : 无法加载文件 C:\Program Files\nodejs\webpack.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c…...

GDAL OGR C++ API 学习之路 (5)OGRLayer篇 代码示例

GetStyleTable virtual OGRStyleTable *GetStyleTable () 返回图层样式表 返回: 指向不应由调用方修改或释放的样式表的指针 // 假设图层对象为 poLayer OGRStyleTable* poStyleTable poLayer->GetStyleTable(); if (poStyleTable ! nullptr) {// 处理样式表信息// ..…...

NIDEC COMPONENTS尼得科科宝滑动型DIP开关各系列介绍

今天AMEYA360对尼得科科宝电子滑动型DIP开关各系列参数进行详细介绍&#xff0c;方便大家选择适合自己的型号。 系列一、滑动型DIP开关 CVS 针脚数&#xff1a;1, 2, 3, 4, 8 安装类型&#xff1a;表面贴装&#xff0c;通孔 可水洗&#xff1a;无 端子类型&#xff1a;PC引脚(只…...

一起学算法(滑动窗口篇)

前言&#xff1a; 对于滑动窗口&#xff0c;有长度固定的窗口&#xff0c;也有长度可变的窗口&#xff0c;一般是基于数组进行求解&#xff0c;对于一个数组中两个相邻的窗口&#xff0c;势必会有一大部分重叠&#xff0c;这部分重叠的内容是不需要重复计算的&#xff0c;所以我…...

HTML <q> 标签

实例 标记短的引用: <q>Here is a short quotation here is a short quotation</q>浏览器支持 元素ChromeIEFirefoxSafariOpera<q>YesYesYesYesYes所有浏览器都支持 <q> 标签。 定义和用法 <q> 标签定义短的引用。 浏览器经常在引用的内容…...

机器学习02-再识K邻近算法(自定义数据集训练及测试)

定义&#xff1a; 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别&#xff0c;则该样本也属于这个类别。简单的说就是根据你的“邻居”来推断出你的类别。 用个成语就是物以类聚 思想&#xff1a; 如果一个样本在特征空间中的K个最…...

github使用笔记及git协作常用命令

1.Github有一个主库,每个人自己也有一个库,称为分支。 2.Github的协作流程:先从主库fork出自己的分支, 然后进行代码的修改等操作, 操作完之后从本地库上推到自己的服务器分支,然后 服务器分支Pull Request到 主库。 3.本地仓库由git维护的三棵“树"组成:第1个…...

iOS - Apple开发者账户添加新测试设备

获取UUID 首先将设备连接XCode&#xff0c;打开Window -> Devices and Simulators&#xff0c;通过下方位置查看 之后登录(苹果开发者网站)[https://developer.apple.com/account/] &#xff0c;点击设备 点击加号添加新设备 填写信息之后点击Continue&#xff0c;并一路继续…...

vue 前端 邮箱、密码、手机号码等输入验证规则

最近在写前端表单验证的时候&#xff0c;发现一篇文章质量很好&#xff0c;所以写下这篇文章记录 原文章链接&#xff1a;vue 邮箱、密码、手机号码等输入验证规则 1.手机号 const checkPhone (rule, value, callback) > {const phoneReg /^1[34578]\d{9}$$/;if (!value…...

如何看待前端已死这个问题(大学生篇)

小编刚大学毕业&#xff0c;还记得是大三的时候选择的前端开发方向&#xff0c;那个时候行情其实并没有这么差&#xff0c;最近互联网上讨论这一个很火的话题&#xff0c;叫前端已死。那么我就说说我的看法吧&#xff0c;虽然可能比起行业的大佬会比较短浅&#xff0c;但我想就…...

揭开高级产品经理思维的秘密

我经常被问到产品经理如何晋升到更高级别。事实上&#xff0c;获得晋升往往是一场复杂的游戏。是的&#xff0c;你的技能和成就很重要&#xff0c;但其他因素也很重要&#xff0c;比如你的经理对人才培养的关心程度、你的同事有多优秀、任期有多长、公司的政治氛围如何等等。 所…...

手把手教你用Claude Desktop的MCP协议,5分钟搞定本地SQLite数据库查询

5分钟实现自然语言查询SQLite&#xff1a;Claude Desktop MCP协议实战指南 想象一下这样的场景&#xff1a;你手头有一个存储着上万条商品信息的SQLite数据库&#xff0c;现在需要快速统计某个品类的库存数量。传统方式可能需要打开数据库工具、编写SQL查询语句&#xff0c;或者…...

【回归儿童本位,重构专业底色】学前教育行业的深度思辨与价值坚守(二)

吕坤阳亲笔二、行业高质量发展的核心&#xff1a;回归儿童&#xff0c;摒弃功利化教育随着学前教育普惠政策的推进&#xff0c;行业规范化程度不断提升&#xff0c;但功利化、形式化的教育倾向依然存在&#xff0c;成为高质量发展的阻碍。部分幼儿园为迎合家长“抢跑”需求&…...

AI Agent工程师进阶指南:掌握核心技能,冲击高薪(P7-P8必备)!

本文详细介绍了AI Agent工程师的能力分层&#xff0c;从API调用工程师到系统设计工程师再到基础设施架构师&#xff0c;明确了不同层级的能力要求和市场现状。文章深入剖析了核心技术栈&#xff0c;包括向量数据库、RAG系统、Agent架构、Memory系统以及生产化工程等关键领域&am…...

终极免费抖音无水印视频下载完整教程:3步快速获取高清素材

终极免费抖音无水印视频下载完整教程&#xff1a;3步快速获取高清素材 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback s…...

Phi-4-mini-reasoning一文详解:专为多步推理设计的开源大模型实战

Phi-4-mini-reasoning一文详解&#xff1a;专为多步推理设计的开源大模型实战 1. 模型概述 Phi-4-mini-reasoning是一款专注于推理任务的文本生成模型&#xff0c;特别擅长处理需要多步分析的复杂问题。与通用聊天模型不同&#xff0c;它被设计用来解决数学题、逻辑题等需要逐…...

原创:国家级高端装备卡脖子技术攻关:五轴联动数控系统核心突破方案

国家级高端装备卡脖子技术攻关&#xff1a;五轴联动数控系统核心突破方案 文章摘要 本项目隶属国家高档数控机床与基础制造装备重大专项&#xff08;04专项&#xff09;&#xff0c;聚焦高端车铣复合车床五轴联动数控系统这一首号卡脖子核心技术&#xff0c;针对该领域海外技术…...

5个步骤掌握MelonLoader:让Unity游戏模组开发变得轻松有趣

5个步骤掌握MelonLoader&#xff1a;让Unity游戏模组开发变得轻松有趣 【免费下载链接】MelonLoader The Worlds First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono 项目地址: https://gitcode.com/gh_mirrors/me/MelonLoader 你是否曾…...

[模电]从PN结到实用电路:二极管的深度解析与设计指南

1. PN结&#xff1a;二极管的物理基础 想象一下把一块P型半导体和N型半导体紧密贴合在一起&#xff0c;就像把两块不同颜色的橡皮泥揉捏在一起。P型半导体里充满了带正电的"空穴"&#xff08;可以理解为缺少电子的位置&#xff09;&#xff0c;而N型半导体则富含自由…...

WAN2.2文生视频效果实测对比:不同SDXL风格对动态连贯性的影响分析

WAN2.2文生视频效果实测对比&#xff1a;不同SDXL风格对动态连贯性的影响分析 最近在玩WAN2.2文生视频模型时&#xff0c;我发现一个挺有意思的现象&#xff1a;虽然模型本身很强大&#xff0c;但生成的视频效果好不好&#xff0c;很大程度上取决于你选的“风格”。WAN2.2集成…...

科哥二次开发Image-to-Video:性能提升39%,小白友好度大增

科哥二次开发Image-to-Video&#xff1a;性能提升39%&#xff0c;小白友好度大增 1. 项目背景与核心价值 Image-to-Video技术正在改变内容创作的方式&#xff0c;它能够将静态图片转化为生动的视频内容。然而&#xff0c;原始I2VGen-XL模型在实际应用中面临两大挑战&#xff…...