【rust中的闭包】

Rust中的闭包

  • 什么是闭包
  • c++中的匿名函数:
  • Rust中的闭包:
  • rust闭包中的三种FN特征:
  • move闭包with Spawn
  • 源代码来看:
  • 总结


什么是闭包

简而言之,闭包就是可以直接访问其外部作用域的函数内部匿名函数(有点狭隘,不过大部分如此)。


c++中的匿名函数:


#include <iostream>
#include <functional>int main() {int a = 7;auto add = [a]( int b) {//这里return a + b;};std::cout << add(4) << std::endl;return 0;
}

可以看到,c++中使用lambda表达式写出的匿名函数需要开发者手动捕获所在作用域中变量的值,

回顾一些C++中的回调函数:
主要作为函数中的参数使用,既函数指针,一般使用时比如作为sort函数的比较函数,for_each中的回调等.

Rust中的闭包:

1 fn main() {
2    let a: i32 = 10;
3    let closure = |b| {a + b};
4    let closure = |b| a + b; //简单写法println!("{}", closure(2));println!("{}", closure(3));
//    println!("{}", closure(1.0));error
}

有人看到第4行代码会疑惑这不是分号结尾返回了()吗,为什么会有返回值? 其实这里只是省略了大括号的简单写法,推荐习惯性使用大括号,避免在代码较多的情况下看漏.
有上述代码可见1. rust中的闭包可以直接捕获环境中的变量.2. 闭包可以类型推导3.编译器类型推导过一次,便已确定,不可以再次推导成其他类型.

rust闭包中的三种FN特征:

  1. FnOnce applies to closures that can be called once. All closures implement at least this trait, because all closures can be called. A closure that moves captured values out of its body will only implement FnOnce and none of the other Fn traits, because it can only be called once.
    只实现fnonce的闭包只能调用一次,它转移了所有权
  2. FnMut applies to closures that don’t move captured values out of their body, but that might mutate the captured values. These closures can be called more than once.
    FnMut实现了可变借用,可以调用多次.
  3. Fn applies to closures that don’t move captured values out of their body and that don’t mutate captured values, as well as closures that capture nothing from their environment. These closures can be called more than once without mutating their environment, which is important in cases such as calling a closure multiple times concurrently
    Fn 不可变借用,并发多次调用闭包时非常有用.

代码示例:

fn test1<F>(closure: F)
whereF: FnOnce(usize) -> bool,
{println!("{}", closure(10));//执行一次,x所有权已经被夺取并再走出闭包作用域后失效println!("{}", closure(11));//error: 使用了已经被move的值.
}fn myFn<F: Fn(String) -> ()>(f: F) {f("world".to_string())
}fn main() {let x = String::from("hello world");test1(|z| z == x.len());let mut len_after_append = |str| {y.push_str(str);y.len()}; //FnMut,需要给闭包变量加mut修饰,既可变的.println!("{}", len_after_append(" coder"));let cc = String::from("hello world");let update_string = |w| println!("{}-{}", cc, w);exec(update_string);//Fn特征闭包调用
}

move闭包with Spawn

使用move闭包可以强制获得变量所有权,这在多线程中spawn运行大于当前函数运行时间的时候非常好用.

use std::thread::{self, sleep};
use std::time;fn test() {let list = vec![1, 2, 3];println!("Before defining closure: {list:?}");thread::spawn(move || {println!("From thread: {list:?}");sleep(time::Duration::from_millis(1000));//模拟运行时长,在长IO下,也尽量使用多线程而不是异步//,否则会有单任务阻塞情况.});println!("completely test");
}
fn main() {test();println!("completely main");
}

打印结果:

Before defining closure: [1, 2, 3]
completely test
completely main
From thread: [1, 2, 3]

源代码来看:


pub trait Fn<Args: Tuple>: FnMut<Args> {/// Performs the call operation.#[unstable(feature = "fn_traits", issue = "29625")]extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}
pub trait FnMut<Args: Tuple>: FnOnce<Args> {/// Performs the call operation.#[unstable(feature = "fn_traits", issue = "29625")]extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

可以看到的是, Fn 和 FnMut 都是 FnOnce 的子特征,因此可以在需要 FnOnce 的地方使用
Fn 或 FnMut的任何实例。


总结

如果你只想调用一次,用Fnonce,如果你想改变用FnMut,如果你想在多线程中使用且不改变用Fn.

“我们都无法确定选择是否正确,只是努力把选择变得正确.”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/6254.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

class com.alibaba.fastjson2.JSONObject cannot be cast to class com.ruoyi.sys

class com.alibaba.fastjson2.JSONObject cannot be cast to class com.ruoyi.sys ry-cloud报错原因解决 ry-cloud 报错 系统监控→在线用户打开后报错 报错信息如下 class com.alibaba.fastjson2.JSONObject cannot be cast to class com.ruoyi.sys原因 type导致&#xff…

靠Python真的能实现经济自由,学会了你也可以

不知道大家有没有注意到&#xff0c;最近关注的很多人都在聊“副业and兼职”这件事。 毕竟单一收入已经不能满足现代人的需求了。 对于普通人来说&#xff0c;想要跳出固定思维和舒适圈&#xff0c;相比于孤注一掷的创业&#xff0c;更推荐兼职。 很多人想要创业&#xff0c;…

掌握 PyQt5:从零开始的桌面应用开发

PyQT5——图形化界面 文章目录 PyQT5——图形化界面集成化图形界面工具为什么使用 \$ProjectFileDir$?示例场景其他 Varaiablespyuic参数解释整体含义示例使用PyQt5和pyuic 创建pyqt5的程序创建一个窗口app.exec\_()和sys.exit(app.exec_())的区别1. app.exec_()2. sys.exit(a…

[HCTF 2018]WarmUp 1

[HCTF 2018]WarmUp 1 审题 观察题目&#xff0c;查看源代码&#xff0c;看到source.php。 访问&#xff0c;看到源代码。 知识点 PHP的代码审计&#xff0c;include函数的应用&#xff0c;文件包含漏洞。 代码审计 <?phphighlight_file(__FILE__);class emmm{public s…

智慧水肥一体化:道品科技现代农业的智能管理模式

智慧水肥一体化是现代农业中一种重要的管理模式&#xff0c;它通过信息技术和物联网技术的结合&#xff0c;实现对水资源和肥料的智能化管理。这一系统的主要功能包括环境监测、集中管理、智能控制、主动报警和数据管理。以下将分别对这些功能进行详细阐述&#xff0c;并探讨智…

UE5.4 PCG 岩石批量复制创建顶部植被

1.复制石头和石头的采点 2.加入想要的植被

卖模版还能赚到钱吗?

说到赚钱&#xff0c;我想大部分人都会感兴趣。但如果告诉大家现阶段卖模板也能赚钱&#xff0c;可能还是有人不信。我要说说我的观察了。 本文可在公众号「德育处主任」免费阅读 我是一只临期程序猿&#xff0c;我最早接触到“模板能卖钱”这个概念是在模板王里。模板王平台上…

怎么样鉴定疾病相关稀有细胞群?二值化精细模型标签,这个刚发的顶刊单细胞算法值得一学!

生信碱移 HiDDEN&#xff1a;抽丝剥茧 在具有病例和对照单细胞RNA测序研究中&#xff0c;样本级标签通常被直接赋予单个细胞&#xff0c;假设所有病例细胞都受影响。这种传统方法在受影响细胞比例较小或扰动强度较弱时&#xff0c;难以有效识别关键细胞及其标记基因&#xff…

第十九周机器学习笔记:GAN的数学理论知识与实际应用的操作

第十九周周报 摘要Abstratc一、机器学习——GAN Basic Theory1. Maximum Likelihood Estimation2. 复习训练GAN的过程3. Objective function与JS散度相关性推导4. GAN的实际做法 总结 摘要 本周周报主要围绕生成对抗网络&#xff08;GAN&#xff09;的基础知识和理论进行深入探…

计算机网络八股文个人总结

1.TCP/IP模型和OSI模型的区别 在计算机网络中&#xff0c;TCP/IP 模型和 OSI 模型是两个重要的网络协议模型。它们帮助我们理解计算机通信的工作原理。以下是它们的主要区别&#xff0c;以通俗易懂的方式进行解释&#xff1a; 1. 模型层数 OSI 模型&#xff1a;有 7 层&#…

Web Workers 学习笔记

最近在开发中遇到了一个需求&#xff0c;一大堆的图片都需要调用两个接口。这对单线程的 JavaScript 运行环境构成了挑战&#xff0c;容易影响用户体验。所以决定学习 Web Workers 并记录一下。 Web Workers 的作用就是提供一个多线程环境&#xff0c;允许将一些繁重任务&…

YOLO11改进|注意力机制篇|引入HAT超分辨率重建模块

目录 一、HAttention注意力机制1.1HAttention注意力介绍1.2HAT核心代码二、添加HAT注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4三、yaml文件与运行3.1yaml文件3.2运行成功截图一、HAttention注意力机制 1.1HAttention注意力介绍 HAT模型 通过结合卷积特征提取与多尺度注意力机…

关于wordpress instagram feed 插件 (现更名为Smash Balloon Social Photo Feed)

插件地址&#xff1a; Smash Balloon Social Photo Feed – Easy Social Feeds Plugin – WordPress 插件 | WordPress.org China 简体中文 安装后&#xff0c;配置教程&#xff1a; Setting up the Instagram Feed Pro WordPress Plugin - Smash Balloon 从这里面开始看就…

ElasticSearch认识

ElasticSearch是什么&#xff1f; Elasticsearch 是一个基于 Apache Lucene 构建的开源分布式搜索引擎和分析引擎。它专为云计算环境设计&#xff0c;提供了一个分布式的、高可用的实时分析和搜索平台。Elasticsearch 可以处理大量数据&#xff0c;并且具备横向扩展能力&#…

在 Google Chrome 上查找并安装 SearchGPT 扩展

ChatGPT 搜索 (SearchGPT)&#xff0c;一个嵌入在流行的 ChatGPT 聊天机器人中的全新搜索引擎&#xff0c;可以改变人们搜索网页的方式。如果你想让它更容易找到并使用它&#xff0c;可以通过安装它的 Chrome 扩展程序。 ChatGPT 搜索是一个快速、精准且无广告的搜索引擎&…

两道算法题

一、算法一 Amazon would like to enforce a password policy that when a user changes their password, the new password cannot be similar to the current one. To determine whether two passwords are similar, they take the new password, choose a set of indices a…

嵌入式硬件电子电路设计(三)电源电路之负电源

引言&#xff1a;在对信号线性度放大要求非常高的应用需要使用双电源运放&#xff0c;比如高精度测量仪器、仪表等;那么就需要给双电源运放提供正负电源。 目录 负电源电路原理 负电源的作用 如何产生负电源 负电源能作功吗&#xff1f; 地的理解 负电压产生电路 BUCK电…

A019基于SpringBoot的校园闲置物品交易系统

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

字节青训-小S的倒排索引

问题描述 小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子&#xff0c;小S决定使用倒排索引。倒排索引的工作原理是&#xff1a;每个单词都会关联一个帖子ID的列表&#xff0c;这些帖子包含该单词&#xff0c;且ID按从小到大的顺序排列。 例…

2024 CSS - 基础保姆级教程系列一

CSS盒子模型 <style>.box {width: 200px;height: 100px;padding: 20px;} </style> <div class"box">盒子模型 </div><style>.box {width: 200px;height: 100px;padding: 20px;box-sizing: border-box;} </style> <div class&…