Rust学习(六):函数式编程
Rust学习(六):函数式编程
我们在前一篇博客中已经介绍了如何通过trait和impl实现Rust的面向对象编程,但是Rust本身实际上并不提倡通过类来解决问题。Rust推崇的是函数式编程,强调将函数作为参数值或者其他函数的返回值,将函数赋值给变量之后在继续执行。其中最重要的两个概念就是:闭包函数和迭代器。
1、闭包函数:
闭包函数是一种可以保存变量或作为参数传递给其他函数使用的匿名函数,和C++中的lambda表达式非常相似,闭包可以在一处创建,然后在不同的上下文中使用,同时闭包函数可以捕获调用者的作用域中的值:
//定义闭包函数:
|parameters| {cody_body;return_value
}
闭包函数还可以进一步简化,Rust可以自动推动闭包函数的参数类型和返回值类型,因此,闭包可以没有参数和返回值:
let is_even = |x| {x % 2 == 0
};let num = 10;
println!("{num} is even {}", is_even(num));
如上面这个案例所示:使用闭包可以只将其赋值给变量,然后就像调用函数一样调用它即可(doge),同时闭包也可以使用外部变量:
let val = 2;
let add_val = |x| {x + val};
let num = 2;
let res = add_val(num);
println!("{num} + {val} = {res}");
如果大家和记得前面对所有权的描述,,那就一定会好奇:这里的闭包函数获取的到底是外部变量的所有权还是外部变量的引用?Rust为此设计了三个trait:
- FnOnce:使用这个trait的闭包函数会获取外部变量的所有权。
- FnMut:获取外部变量的可变引用。
- Fn:获取外部变量的借用值。
如果需要强制将外部变量所有权转移到闭包内,那么可以使用move关键字:
let val = 2;
let add_val = move |x| {x+val};
2、迭代器:
迭代器会把集合中所有元素按照顺序一个一个传递给处理逻辑,允许对一个序列进行某些处理,并且会遍历这个序列中的每一项以决定何时结束。我们之前使用的for循环就是一个迭代器,迭代器默认实现了Iterator trait——iter(),用于返回i迭代器和next(),用于返回迭代器的下一项,他们是迭代器的核心功能!
根据迭代器迭代时是否可以修改数据,iter()方法有三个版本:
- iter():返回只读可重入迭代器,元素类型:&T
- iter_mut():返回可修改可重入迭代器,元素类型:&mut T
- into_iter():返回只读不可重入迭代器,元素类型:T
可重入是指:迭代后原始数据还能使用,不可重入则代表迭代器消费了原始数据(这里可以借用python中的pop()方法,取出元素,并删除)
let nums = vec![1, 2, 3, 4, 5, 6];//使用iter()方法:
for num in nums.iter() {println!("num:{num}");
}
println!("{:?}", nums); //可以使用原数据nums//使用iter_mut()方法:
for num in nums.iter_mut() {*num += 1;
}
println!("{:?}", nums); //可以使用原数据nums//使用into_iter()方法:
for num in nums.into_iter() {println!("num:{num}");
}
//for num in nums.iter() {println!("num:{num}");} 错误!nums已经被消费
消费是迭代器中的一种有趣且特殊的操作,sum, next, nth, fold等都是消费者,他们会对迭代器进行操作,得到最终值:
fn main() {let nums = vec![1, 2, 3, 4, 5, 6];let nums_iter = nums.iter();let total = nums_iter.sum::<i32>();let new_nums : Vec<i32> = (0..100).filter(|&n| n % 2 == 0).collect();println!("{:?}", new_nums);// 求小于等于1000的能被3或5整除的所有整数之和:let sum = (1..1000).filter(|n| n % 3 == 0 || n % 5 == 0).sum::<u32>();println!("{sum}");
}
实际上,除了函数式编程之外,还有命令式编程、声明式编程等多种编程范式。我们平时所用的面向对象编程(C++和python)和结构式编程(C)都属于命令式编程,命令式编程的主要思想是一步一步的精确的给出计算机运行程序的指令,而声明式编程(SQL)则以数据结构的形式表达变成逻辑,主要思想是告诉计算机应该做什么,而不是具体怎么做的(其实有点夸大了),函数式编程的思想和声明式编程类似,它更进一步是面向数学的抽象,旨在将计算描述为一种数学表达式求值,寻求一种输入输出的映射关系。
相关文章:
Rust学习(六):函数式编程
Rust学习(六):函数式编程 我们在前一篇博客中已经介绍了如何通过trait和impl实现Rust的面向对象编程,但是Rust本身实际上并不提倡通过类来解决问题。Rust推崇的是函数式编程,强调将函数作为参数值或者其他函数的返回值…...
使用 Vue 和 Create-Vue 构建工程化前端项目
目录 前言1. 工程化的意义与 Vue 的生态支持2. 搭建 Vue 工程化项目2.1 环境准备2.2 使用 create-vue 创建项目2.2.1 初始化项目2.2.2 安装依赖2.2.3 本地运行 3. Vue 项目的目录结构解析4. Vue 开发流程详解4.1 项目入口与根组件4.1.1 main.js 的作用4.1.2 App.vue 的结构 4.2…...
opencv图片明暗度判断方法
OpenCV 的LAB 颜色空间(也称为 CIELAB)是一种颜色对手的颜色模型,它旨在模仿人类的色彩感知。LAB 颜色空间由三个分量组成: L: 亮度分量 (Lightness),范围从 0(黑色)到 100(白色&…...
QT6学习第三天
QT6学习第三天 第一个Widgets项目创建项目项目界面简单介绍编译文件介绍 我在第一天中将重点标了颜色,后边我把一些简单的东西都不写了,写了的都是实际用的东西,就不标颜色了。 第一个Widgets项目 首先我们创建一个widgets项目,…...
计算机网络-MSTP基础实验一(单域多实例)
前面我们已经大致了解了MSTP的基本概念和工作原理,但是我自己也觉得MSTP的理论很复杂不结合实验是很难搞懂的,今天来做一个配套的小实验以及一些配置命令。 一、网络拓扑 单域多实例拓扑 基本需求:SW1为VLAN10的网关,SW2为VLAN20的…...
React合成事件及其核心思想详解
相关联Javascript知识 1.JavaScript 的事件流 事件流是 JavaScript 处理事件的机制,它描述了事件从发生到被处理的过程。事件流主要包括两个阶段:捕获阶段和冒泡阶段。在捕获阶段,事件从文档的根元素开始,逐层向下传播到目标元素&…...
Datawhale模型减肥秘籍Tasking之模型量化
Datawhale模型减肥秘籍Tasking之模型量化 什么是量化?为什么量化?量化基本方法基于k-means的量化线性量化 训练后量化量化粒度动态量化参数的计算 ( Cliping )指数移动平均(EMA)Min-MaxKL 量化均方误差(MSE)…...
在云服务器搭建 Docker
操作场景 本文档介绍如何在腾讯云云服务器上搭建和使用 Docker。本文适用于熟悉 Linux 操作系统,刚开始使用腾讯云云服务器的开发者。如需了解更多关于 Docker 相关信息,请参见 Docker 官方。 说明: Windows Subsystem for Linuxÿ…...
Redis 的代理类注入失败,连不上 redis
在测试 redis 是否成功连接时,发现 bean 没有被创建成功,导致报错 根据报错提示,需要我们添加依赖: <dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>&l…...
版本控制【Git Bash】【Gitee】
目录 一、什么是版本控制? 二、版本控制的种类: 1、本地版本控制 2、集中版本控制 3、分布式版本控制 三、下载Git Bash 四、Git Bash 配置 五、Git Bash使用 1、切换目录:cd 2.查看当前文件路径:pwd 3.列出当前目录下文件…...
Neo4j Desktop 和 Neo4j Community Edition 区别
Neo4j Desktop 和 Neo4j Community Edition 的主要区别在于它们的用途、功能以及安装和管理方式。以下是这两者的详细对比: 1. Neo4j Desktop Neo4j Desktop 是一个图形化的桌面应用程序,主要为开发人员和个人使用提供了一个便捷的环境来安装、管理和运…...
使用uniapp开发微信小程序使用uni_modules导致主包文件过大,无法发布的解决方法
在使用uniapp开发微信小程序时候,过多的引入uni_modules的组件库,会导致主包文件过大,导致无法上传微信小程序,主包要求大小不超过1.5MB.分包大小每个不能超过2M。 解决方法:分包。 1.对每个除了主页面navbar的页面进…...
HarmonyOS NEXT应用元服务开发Intents Kit(意图框架服务)事件推荐开发者测试
意图框架向开发者提供真机测试能力,即开发者可连接设备进行调测。开发者完成代码开发之后,功能正式上架应用市场前,可以在HarmonyOS NEXT设备上面进行自验证,打磨体验。真机测试分为三个步骤:基础信息提供,…...
GD32F103 实践-- MCU编译运行
编译 打开固件库示例工程:在SDK路径下找到固件库示例工程,路径通常是SDK\GD32F10x_Firmware_Library_Template\Keil5_project\Project 选择芯片型号:根据你的MCU型号选择,例如GD32F103RCT6 修改宏定义:根据MCU型号修…...
SQL复杂数据类型处理
背景 数据处理中,经常碰到复杂数据类型,需要将他们进行解析才能利用。 复杂数据类型 1、MAP结构转为列 WITH tmp AS ( SELECT {"Users":{"4418":{"UserId":4418,"Score":0,"IsStudent":true},&q…...
ROS第九梯:ROS+VSCode+Python+C++自定义消息发布和订阅
首先,Python版本的ROS项目和C++版本的ROS项目前期创建功能包的步骤基本一致,具体可参考第二章。 费一步:新建msg文件 在功能包(data_input)目录下创建一个msg文件夹,并在msg文件夹下创建一个名为Box的msg文件,具体如下图所示: 该msg文件为一个用于描述3D Box的文件,…...
【Linux】指令 + 压缩与解压
Linux 一.Linux基本指令1.grep2.zip和unzip1.Linux中的压缩文件发送Windows中2.Linux中接收Windows中压缩文件 3.tar(重要)1.Linux与Linux互传压缩文件 4.bc5.uname 二.Linux相关知识点1.Linux常用热键2.关机操作 一.Linux基本指令 1.grep 行文本过滤工…...
力扣(leetcode)题目总结——动态规划篇
leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏:点击进入 leetcode题目分类 关注走一波 前言:本系列文章初衷是为了按类别整理出力扣(leetcode)最经典题目,…...
数据仓库数据湖湖仓一体解决方案
一、资料介绍 数据仓库与数据湖是现代数据管理的两大核心概念。数据仓库是结构化的数据存储仓库,用于支持企业的决策分析,其数据经过清洗、整合,以固定的模式存储,适合复杂查询。数据湖则是一个集中存储大量原始数据的存储库&…...
微信小程序 最新获取用户头像以及用户名
一.在小程序改版为了安全起见 使用用户填写来获取头像以及用户名 二.代码实现 <view class"login_box"><!-- 头像 --><view class"avator_box"><button wx:if"{{ !userInfo.avatarUrl }}" class"avatorbtn" op…...
无人机在森林中的应用!
一、森林资源调查 无人机可以利用遥感技术快速获取所需区域高精度的空间遥感信息,对森林图斑进行精确区划。相较于传统手段,无人机调查具有低成本、高效率、高时效的特点,尤其在地理环境条件不好的区域,调查人员无法或难以到达的…...
Seatunnel解决Excel中无法将数字类型转换成字符串类型以及源码打包
需求 需要实现将Excel中的数字类型的单元格像数据库中字符串类型的字段中推送 问题原因 Seatunnel在读取字段类型的时候都是使用强转的形式去获取数据的 假如说数据类型不一样的话直接强转就会报错 修改位置 org/apache/seatunnel/api/table/type/SeaTunnelRow.java org…...
在阿里云快速启动Appsmith搭建前端页面
什么是Appsmith Appsmith是一个开源的低代码开发平台,它使得开发者能够快速地构建内部工具、业务管理系统、CRM系统等。Appsmith通过提供一系列预建的UI组件(如表格、图表、表单等),以及对数据库、API调用的直接支持,…...
「51媒体」:企业成长助推器
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 「51媒体」(51meiti media PR)作为国内具有影响力的媒体邀约服务商,确实在助力企业成长方面发挥着重要作用。以下是对「51媒体」的详细介绍࿰…...
安全、便捷、效率高,明达边缘计算网关助力制药装备企业远程调机
随着药厂对设备运维需求的增长,制药装备企业需要在提高运维效率的同时,降低人工及差旅成本。制药装备因其数据具有高度的保密性,要求运维工程师提供安全可靠的远程调试方式。本案例介绍了明达技术MBox20系列5口WIFI通用网关在制药装备上的应用…...
海康威视和大华视频设备对接方案
目录 一、海康威视 【老版本】 【新版本】 二、大华 一、海康威视 【老版本】 URL规定: rtsp://username:password[ipaddress]/[videotype]/ch[number]/[streamtype] 注:VLC可以支持解析URL里的用户名密码,实际发给设备的RTSP请求不支…...
用DMA来自动控制PWM的输出(音频输出,交直流转换)
一、前提分析 举例:一首歌所包含的音阶有高有低,而按照某种编曲的顺序排列也就对应了不同的频率(五线谱:1234567 对应的音阶各不相同)所以频率可以理解为它的源头。频率的来源又可由PWM来控制故而一首歌所包含的频率序…...
利用hive元数据统计数据量
对于数据量的统计,从表是否分区分为分区表和非分区表两者有着不同的统计方式 非分区表 1. 利用传统方法count 2. 利用元数据计算: select sum(tb.param_value) AS TOTAL from sys.tbls t left join sys.dbs d on t.db_id d.db_id left join sys.tabl…...
平均值(水题???)
今天刷题时发现了一道十分难简单的题。大家仔细看看题目。 题目 5. K11937 平均值 题目描述 在演讲比赛中,当参赛者完成演讲时,评委会对他的表演进行评分。工作人员会去掉一个最高分,一个最低分,然后计算其余的平均值作为参赛者…...
免费开源!DBdoctor推出开源版系统诊断工具systool
前言 在开发和运维过程中,经常会遇到难以定位的应用问题,我们通常需要借助Linux系统资源监控工具来辅助诊断。然而,系统的IO、网络、CPU使用率以及文件句柄等信息通常需要通过多个独立的命令工具来获取。在没有部署如Prometheus这样的综合…...
网站漂浮图片/什么是网络营销策略
传统的序列化很明显这种序列化有一个问题,虽然能满足append的存储模式,但无法从中读取第n个对象,每次得从第一个开始读。kafka作为一种C-S架构,C端需要和S端进行通信,批量向S端传送序列化的对象,达到batch.…...
源码网站python免费/接外包项目的网站
欢迎使用 Cmd Markdown 编辑阅读器 我们理解您需要更便捷更高效的工具记录思想,整理笔记、知识,并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 —— 我们为记录思想和分享知识提供更专业的工具。 您可以使用 Cmd Markdown&…...
饿了吗网站如何做/百度怎么推广自己的作品
今天开始讲了java中很重要的一个知识点,那就是方法(函数) 什么是方法: 定义:能够实现某种特定功能的代码块。 语法: 修饰符 返回值类型 方法名(参数列表){ 方法体;…...
越秀建设网站/营销网站都有哪些
1. 题目 剑指 Offer 03. 数组中重复的数字 2. 描述 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任…...
广州门户网站/网站推广优化流程
结合help中给的例子,又使用DisPlayFeedBack,实现在鹰眼中拖动。拖动过程中小边框的显示问题解决的不是很好,还望大家多多指教。实现如下:两个MapControl控件:axMapControl1和axMapControl2,axMapControl2存…...
织梦网站手机版怎么做/客源软件哪个最好
2019独角兽企业重金招聘Python工程师标准>>> 原因:缺少Mapper接口的xml配置文件造成的问题。 (1)逆向工程生成的xml文件和java文件一般放在resources文件夹下 (2)出现这样的问题,是因为xml文件的…...