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 )。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】C语言基础语法速览

C语言基础语法目录 C语言基础语法速览1. 变量类型1.1 类型字节数1.1 变量输出格式1.2 变量输入格式 2. 分支循环语句2.1 if分支语句2.2 switch 分支语句2.3 while循环语句2.4 do...while循环语句2.5 for循环语句 3. 数组3.1 一维数组3.2 二维数组 4. 结构体4.1 结构体类型定义4…

4个宝藏网站,免费即用,办公运营效率利器!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 有很多朋友在日常办公时&#xff0c;需要发送邮件&#xff1b;在新媒体运营、设计及前端开发等工作场合中&#xff0c;都或多或少会遇上图片、视频等文件太大及格式问题需要压缩和转换…

数据结构(三)栈 队列 数组

2024年5月26日一稿(王道P78) 栈 基本概念 基本操作 顺序存储结构 基本操作 共享栈

微信小程序开发 懒加载+瀑布流+排序功能

在小程序的开发过程中&#xff0c;遇到了这样的功能需求&#xff1a;在保持瀑布流布局的情况下&#xff0c;使用懒加载来渲染页面&#xff0c;并且要求对其中的属性添加排序功能。 单独拿出来都是很好实现的功能&#xff0c;但是当三个功能联系在一起时&#xff0c;问题就出现…

数智乡村:是不是乡村治理治理的巨大进步呢?

一、什么是数智乡村 数智乡村是指借助信息技术和数据分析等手段&#xff0c;对乡村进行智能化管理和服务的模式。它可以提供更高效、精准、便利的服务&#xff0c;促进乡村经济发展和社会治理改善。因此&#xff0c;数智乡村确实可以被视为乡村治理的巨大进步。 二、数智乡村的…

大一久富农机实习与商业思维学习计划

学习目标&#xff1a; 大一久富农机实习与商业思维学习计划 一、目标 完成久富农机的实习&#xff0c;增强对农机行业的了解和实际操作能力。提升自身的商业思维能力&#xff0c;为未来的职业生涯打下坚实基础。组织并带领同学院的同学一起参加实习&#xff0c;增强团队合作…

腾讯发布ELLA:为扩散模型注入LLM能力,提升复杂场景的图像生成,准确率超90%

前言 近年来&#xff0c;基于扩散模型的文本到图像生成技术取得了显著进步&#xff0c;能够生成高质量、逼真的图像。然而&#xff0c;大多数扩散模型仍然使用CLIP作为文本编码器&#xff0c;这限制了它们理解复杂提示的能力&#xff0c;例如包含多个物体、详细属性、复杂关系…

python-pytorch seq2seq+luong dot attention笔记1.0.3

python-pytorch seq2seq+luong dot attention笔记1.0.0 可复用部分编写encoder编写Attention编写decoder编写seq2seq设定模型参数模型训练使用模型使用总结下一步参考链接可复用部分 主要将数据弄成如下格式: seq_example = [“你认识我吗”, “你住在哪里”, “你知道我的名…

ROS 2边学边练(51)-- 构建自定义(消息类型)RViz显示项

前言 一俩礼拜没有更新了&#xff0c;今天突然发现ROS 2突然有了新版本了&#xff0c;名为Jazzy&#xff0c;这更新速度与Qt有的一比。这么长时间没更新呢&#xff0c;一来工作上来活了&#xff0c;没那么多时间来继续ROS这块&#xff0c;二来&#xff0c;人懈怠了一点&#xf…

Grafana HTML Panel展示post获取后数据

<!DOCTYPE html> <html> <head><title>API 数据表格展示</title><script src"https://code.jquery.com/jquery-3.6.0.min.js"></script> </head> <body><table id"data-table" border"1&qu…

航运复兴?大摩不信!

大摩认为&#xff0c;从供需关系来看红海危机只是推迟了航运业下行周期的到来&#xff0c;一旦干扰消除&#xff0c;行业可能重回周期性低迷。 红海危机加剧运力紧张&#xff0c;航运市场价格飞涨。 大摩在24日的一份报告中指出&#xff0c;受红海危机干扰航运市场运力&#…

Spring Boot+Debezium:解决 MySQL Binlog监听

在当今的企业应用中&#xff0c;对数据变更进行实时捕获和处理是至关重要的。而Debezium作为一个强大的开源平台&#xff0c;能够实时捕获数据库的变化事件&#xff0c;为实时数据流处理提供了可靠的解决方案。在本文中&#xff0c;我们将探讨如何将Debezium与SpringBoot项目无…

Springboot集成GRPC

Springboot集成GRPC 一、springboot版本二、GRPC的pom依赖2.1 服务端2.2 客户端3.构建依赖 三、配置文件服务端客户端 四、 demo4.1 编写proto文件4.2 生成文件4.3 服务端重写方法4.4 客户端调用该方法 五、测试 一、springboot版本 <groupId>org.springframework.boot&l…

pycharm找不到conda可执行文件解决办法

解决办法 1、第一种 按照以下步骤&#xff0c;找到condabin文件下面&#xff0c;conda.bat 文件&#xff0c;把路径给复制下来&#xff0c;粘贴到 Conda 可执行文件&#xff0c;即可。 然后再点击加载环境&#xff0c;我这里是已经汉化了 pycharm &#xff0c;如何汉化&…

Linux - 用户管理

1 基本介绍 Linux系统是一个多用户多任务的操作系统&#xff0c;任何一个要使用系统资源的用户&#xff0c;都必须先向系统管理员申请一个账号&#xff0c;然后以这个账号的身份进入系统 2 添加用户 基本语法 //添加用户 useradd 用户名 实列(root权限下) useradd huchen…

Less语法

一:less作用 是CSS的预处理器,扩充了CSS语言,使CSS具有一定逻辑性、计算功能;通了less语法,生成.CSS文件; 二:具体使用规则 1 less变量设置属性值 语法规范: @变量名:属性值名;CSS属性:@变量名;eg:给box盒子添加粉色背景 @bgcolor:purple; .box{background-col…

C++——list的实现以及源码

前言&#xff1a; 最近学习了clist的实现&#xff0c;这让我对迭代器的理解又上升了一个新的高度&#xff0c;注意&#xff1a;代码里的list是放在一个叫zgw的命名空间里边&#xff0c;但是在实现list的代码中没有加namespace&#xff0c;这里给个注意&#xff0c;以后复习时能…

解密论文评审过程:SCI论文是匿名送审的吗?

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 前几天有位学员问我&#xff0c;审稿人能看见我论文的作者和单位信息吗&#xff1f;应该是双方都匿名才更公平啊。 同行评议&#xff0c;在不同的期刊操作还真不一样。有双方…

spring学习笔记一

前言&#xff08;第一性原理&#xff09; 那么spring解决问题&#xff1a;JAVA开发框架&#xff0c;spring是用来解决企业级Java应用开发的问题。 通过依赖注入和面向切面编程来灵活管理和配置代码&#xff0c;提供一套工具来帮助开发和配置代码&#xff0c;提供了声明式事务…