Rust之函数、单元测试
1、函数
类似于C++函数。
1.1、普通函数
在Rust中,函数的定义使用fn关键字,后跟函数名、参数列表、返回类型和函数体。函数体由一系列语句组成,用于执行特定的操作和计算。
函数定义:
使用fn关键字定义函数,函数由函数签名和函数体组成。
函数签名由函数名、参数、返回值类型组成。函数体包含于{}内,是函数要执行的具体代码。
函数体:
函数体由一系列语句和一个可选的结尾表达式构成。
结尾表达式没有分号,代表这是一个表达式而非语句,将会自动返回表达式的值;
结尾表示式的结尾如果加上分号,就变成了语句,语句没有返回值。
函数参数:
是函数签名的一部分。
函数参数必须明确指定数据类型,但不能指定默认值。
函数参数可以分为可变和不可变参数,默认不可变参数,需要可变操作时,需要加上mut关键字。
返回值:
如果函数需要返回值给调用者,在函数定义时需要明确返回值类型。使用 -> 数据类型来定义。
函数只能有一个返回值,需要返回多个值时,可以使用元组类型。
Rust中每个函数都有返回值,即使没有显示返回值的函数,也会隐式地返回一个单元值()。
一般,函数隐式地返回函数体最后一个表达式的值,可以使用return 语句来显示返回。
代码:
// 文件名: a-1/src/main.rsfn add(a: i32, b: i32) -> i32 {a + b
}fn main() {let result = add(3, 5);println!("Result: {}", result);
}
结果:
[root@local_tmp]#
[root@local_tmp]# cargo runCompiling a-1 v0.1.0 (/home/test/rust/a-1)Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15sRunning `target/debug/a-1`
Result: 8
[root@local_tmp]#
[root@local_tmp]#
1.2、函数作为参数和返回值
在Rust中,函数可以作为参数传递给其他函数,也可以作为函数的返回值。
// 文件名:a-1/src/main.rsfn add(a: i32, b: i32) -> i32 {a + b
}fn subtract(a: i32, b: i32) -> i32 {a - b
}fn calculate(op: fn(i32, i32) -> i32, a: i32, b: i32) -> i32 {op(a, b)
}fn main() {let result1 = calculate(add, 3, 5);let result2 = calculate(subtract, 8, 4);println!("Result 1: {}", result1);println!("Result 2: {}", result2);
}
结果:
[root@local_tmp]#
[root@local_tmp]# Cargo runCompiling a-1 v0.1.0 (/home/work/test/rust/a-1)Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15sRunning `target/debug/a-1`
Result 1: 8
Result 2: 4
[root@local_tmp]#
[root@local_tmp]#
在上述示例中,定义了两个简单的函数add和subtract,分别用于相加和相减操作。然后,定义了一个名为calculate的函数,它接收一个函数参数op,类型为fn(i32, i32) -> i32,表示接收两个i32类型参数并返回i32类型结果的函数。在函数体中,我们调用了op函数,并传递了a和b作为参数。
在main函数中,我们分别使用add和subtract作为calculate函数的参数,并打印出计算结果。
1.3、函数重载
在 Rust 中,严格来说,并没有传统意义上的函数重载。传统的函数重载通常指的是在同一作用域内定义多个同名函数,但参数个数或类型不同。然而,在 Rust 中,函数名字是唯一的,无法直接定义同名函数。不过,Rust提供了更为灵活的方式来处理类似的情况。
// 文件名:a-1/src/main.rstrait Add {type Output;fn add(self, other: Self) -> Self::Output;
}impl Add for i32 {type Output = i32;fn add(self, other: Self) -> Self::Output {self + other}
}impl Add for f64 {type Output = f64;fn add(self, other: Self) -> Self::Output {self + other}
}fn main() {let a = 3;let b = 5;let c = 2.5;let d = 4.8;let result1 = a.add(b);let result2 = c.add(d);println!("Result 1: {}", result1);println!("Result 2: {}", result2);
}
结果:
[root@local_tmp]#
[root@local_tmp]# Cargo runCompiling a-1 v0.1.0 (/home/work/test/rust/a-1)Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15sRunning `target/debug/a-1`
Result 1: 8
Result 2: 7.3
[root@local_tmp]#
[root@local_tmp]#
1.3、参数个数不确定函数
1.4、泛型函数
在 Rust 中,函数模板通常被称为【泛型函数】。是同时可以处理多种类型的函数,而不需要为每种类型编写一个单独的函数。这样可以减少代码重复,并提高代码的可读性和可维护性。
在Rust中,泛型通常使用<T>表示,当然,不一定要是T,它也可以是A、B、C、D、E、F、G等。
2、单元测试
在Rust中,可以使用cargo test完成对单元测试代码的测试。
// 文件名:a-1/src/main.rspub fn add(a: i32, b: i32) -> i32 {a + b
}#[cfg(test)]
mod tests_1 {use super::*;#[test]fn test_add() {assert_eq!(add(2, 3), 5);assert_eq!(add(-2, 3), 1);assert_eq!(add(0, 0), 0);}
}fn main() {println!(" 10 + 3 = {}", add(10, 3));
}// 测试struct
struct Rectangle {width: u32,height: u32,
}impl Rectangle {fn area(&self) -> u32 {self.width * self.height}
}#[cfg(test)]
mod tests_2 {use super::*;#[test]fn test_rectangle_area() {let rect = Rectangle { width: 10, height: 20 };assert_eq!(rect.area(), 200);}
}/*
说明:
(1) 在源代码文件的顶部使用 #[test] 属性来标记一个函数作为测试函数;上文中 test_add() 是测试函数;
(2) #[cfg(test)] 是一个条件编译属性,它允许编写只在测试构建中编译的代码。这对于定义只在测试时需要的辅助函数、类型或模块特别有用,从而避免在生产代码中引入不必要的开销或依赖。即只在执行 cargo test 的时候才编译、运行。
*//*
(1) use super::* 是一种模块系统的特性,它允许你在当前模块中引入父模块中定义的所有公共项。这在编写单元测试时非常有用,可以在测试模块中引入要测试的模块(也就是正在编写的那个模块)中的所有公共函数。
*/
结果:
[root@local_tmp]#
[root@local_tmp]# cargo runCompiling a-1 v0.1.0 (/home/test/rust/a-1)Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14sRunning `target/debug/a-1`10 + 3 = 13
[root@local_tmp]#
[root@local_tmp]#
[root@local_tmp]# cargo testCompiling a-1 v0.1.0 (/home/test/rust/a-1)Finished `test` profile [unoptimized + debuginfo] target(s) in 0.21sRunning unittests src/main.rs (target/debug/deps/a_1-17ff21ae49a735eb)running 2 tests
test tests_1::test_add ... ok
test tests_2::test_rectangle_area ... oktest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
[root@local_tmp]#
[root@local_tmp]#
断言:
| 关键字 | 说明 |
| assert! | 检查给定的布尔表达式是否为真。如果为假,则测试失败。 |
| assert_eq! | 检查两个表达式是否相等。如果不等,则测试失败。 |
| assert_ne! | 检查两个表达式是否不相等。如果相等,则测试失败。 |
| Assert_debug_snapshot! | 用于比较当前代码的调试输出是否与先前存储的快照匹配,这有助于在重构代码时确保其行为未改变 (依赖 insta )。 |
相关文章:
Rust之函数、单元测试
1、函数 类似于C函数。 1.1、普通函数 在Rust中,函数的定义使用fn关键字,后跟函数名、参数列表、返回类型和函数体。函数体由一系列语句组成,用于执行特定的操作和计算。 函数定义: 使用fn关键字定义函数,函数由函数…...
Linux环境下TensorFlow安装教程
TensorFlow是学习深度学习时常用的Python神经网络框 下面以Mask R-CNN 的环境配置为例: 首先进入官网:www.tensorflow.org TensorFlow安装的总界面: 新建anaconda虚拟环境: conda create -n envtf2 python3.8 (Pyth…...
基于Open3D的点云处理19-模拟生成点云
如果没有设备,怎么得到点云进行学习研究呢,一般通过以下方法: 模型采样+增加噪声:简单方便,但结果比较理想与真实扫描不一致;光线投射:简单方便,可以模仿传感器的一个扫描视角Blensor点云仿真:能够模仿传感器本身的一些噪声,适合激光雷达和tof相机的仿真,传感器较少…...
安全分析[1]之网络协议脆弱性分析
文章目录 威胁网络安全的主要因素计算机网络概述网络体系结构 网络体系结构脆弱性分组交换认证与可追踪性尽力而为匿名与隐私对全球网络基础实施的依赖无尺度网络互联网的级联特性中间盒子 典型网络协议脆弱性IP协议安全性分析IPSec(IP Security)IPv6问题 ICMP协议安…...
数据湖对比(hudi,iceberg,paimon,Delta)
Delta 数据湖 Delta 更新原理 update/delete/merge 实现均基于spark的join功能。 定位 做基于spark做流批一体的数据处理 缺点 本质为批处理。强绑定spark引擎。整体性能相较其他数据湖比较差 hudi 数据湖 hudi 更新原理 通过hudi自定义的主键索引hoodiekey 布隆过…...
基于ssm的蛋糕商城系统java项目jsp项目javaweb
文章目录 蛋糕商城系统一、项目演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目源码(9.9¥带走) 蛋糕商城系统 一、项目演示 蛋糕商城管理系统 二、项目介绍 系统角色 : 管理员、用户 一,管理员 管理员有…...
vue3父组件使用ref获取子组件的属性和方法
在vue3中父组件访问子组件中的属性和方法是需要借助于ref: 1.<script setup> 中定义响应式变量 例如: const demo1 ref(null) 2.在引入的子组件标签上绑定ref属性的值与定义的响应式变量同名( <demo1 ref"demo1"/>)。 父组件代码如下&…...
加入MongoDB AI创新者计划,携手MongoDB共同开创AI新纪元
加入MongoDB AI创新者计划! MongoDB对AI创新和初创企业的支持既全面又广泛!无论您是领先的AI初创企业还是刚刚起步,MongoDB Atlas都是支持您愿景的最佳平台。 AI 初创者计划The AI Startup Track AI初创者计划为早期初创企业提供专属福利&…...
3. CSS的色彩与背景
3.1 CSS3中的色彩 CSS3扩展了颜色的定义方式,使得开发者能够使用更多样化和灵活的颜色表达方式。这包括RGB、RGBA、HSL、HSLA等格式,以及支持透明度和渐变的特性。 3.1.1 颜色格式 十六进制颜色 十六进制颜色是最常用的颜色表示法,以#开头…...
MiniCPM-Llama3-V-2_5-int4
MiniCPM-Llama3-V-2_5-int4大模型部署使用环境: python3.8cuda11.8其它要求,按照安装文档要求下载即可 我是在算力平台用4090跑的, GPU 显存(8GB)可以部署推理 int4 量化版本,如果推理非量化版本需要更高显…...
压缩能力登顶 小丸工具箱 V1.0 绿色便携版
平常录制视频或下载保存的视频时长往往都很长,很多时候都想要裁剪、 截取出一些“精华片段”保留下来,而不必保存一整个大型视频那么浪费硬盘空间… 但如今手机或电脑上大多数的视频剪辑软件,切割视频一般都要等待很长时间导出或转换&#…...
电子电器架构 - 车载网管功能简介
电子电器架构 - 车载网管功能简介 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,…...
路由配置总结
在 Vue 中,一级路由和二级路由的配置主要依赖于 vue-router 插件。以下是关于一级路由和二级路由配置的总结: 一、安装 vue-router 你可以通过 npm 或 yarn 来安装 vue-router。在命令行中运行以下命令: 使用 npm: npm install vue-router…...
从零起航,Python编程全攻略
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、Python入门之旅 二、Python进阶之道 三、Python爬虫实战 四、Python数据分析利器 五…...
正运动视觉与运动一体机小课堂----三分钟系列
【视觉运控一体机小课堂】三分钟搭建机器视觉开发环境-正运动技术 (zmotion.com.cn) 【视觉运控一体机小课堂】三分钟读取本地图像-正运动技术 (zmotion.com.cn) 【视觉运控一体机小课堂】三分钟实现相机采集和图像保存-正运动技术 (zmotion.com.cn) 【视觉运控一体机小课堂…...
微信小程序如何跳转微信公众号
1. 微信小程序如何跳转微信公众号 1.2. 微信公众号配置 登录微信公众号,点击【小程序管理】: 点击【添加】: 点击【关联小程序】: 输入小程序进行关联: 1.2. 微信小程序配置 登录微信小程序…...
vi和vim编辑器
目录 1 vi和vim的基本介绍 2 vi和vim常用的三种模式 1)正常模式 2)插入模式 3)命令行模式 3 vim快捷键 1)普通模式下: 2)输入模式 3)命令行模式 4)可视模式 1 vi和vim的基本…...
纯电动汽车硬件在环测试
纯电动汽车硬件在环测试技术研究综述 1、新能源汽车概述 随着新能源汽车“电动化、智能化、网联化、共享化”进程的不断推进,新能源汽车的整体性能得到显著提高,纯电动汽车已经逐渐走进大众视野,消费者对于新能源汽车的认可度和购买欲望也稳…...
Flutter 中的 ClipRect 小部件:全面指南
Flutter 中的 ClipRect 小部件:全面指南 在Flutter中,ClipRect是一个布局小部件,它使用矩形裁剪其子组件的可见部分。这意味着超出ClipRect定义的矩形区域的子组件部分将被隐藏。ClipRect通常用于实现自定义的滚动效果、动画或者仅仅是为了限…...
【LeetCode】【209】长度最小的子数组(1488字)
文章目录 [toc]题目描述样例输入输出与解释样例1样例2样例3 提示进阶Python实现前缀和二分查找滑动窗口 个人主页:丷从心 系列专栏:LeetCode 刷题指南:LeetCode刷题指南 题目描述 给定一个含有n个正整数的数组和一个正整数target找出该数组…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
