Rust之抽空学习系列(四)—— 编程通用概念(下)

Rust之抽空学习系列(四)—— 编程通用概念(下)

1、函数

函数用来对功能逻辑进行封装,能够增强复用、提高代码的可读

以下是函数的主要组成部分:

  • 名称
  • 参数
  • 返回类型
  • 函数体

1.1、函数名称

在Rust中,函数通过fn关键字进行声明,并且函数的名称遵循蛇形命名法,即名称使用小写字母进行组合,单词与单词之间使用下划线进行分割,这点倒是和Python中的函数命名方式倒是相一致的

其实,在Rust中函数和变量通常都应该采用蛇形命名法

维基百科:蛇形命名法

fn make_money() {   // 蛇形命名法println!("赚钱");
}fn main() {   // 作为入口的main()函数// 函数调用,函数名加(参数),现在没有参数就是()make_money();  
}

刚刚是先定义的函数,再在main中进行调用,这个顺序反过来也不影响,这个可以和某些编程语言的写法区分一下

fn main() {make_money();
}
// 放在后面也可以
fn make_money() {println!("赚钱");
}

函数可以先定义或后定义,只要对于使用区域可见即可

1.2、函数参数

函数的参数可以将外部的变化灵活地告诉内部的逻辑,在框架不变的前提下随机应变,作为函数签名的一部分,就像在文档上看到的那样
在这里插入图片描述

fn main() {make_money(3);     // 传入具体的参数
}fn make_money(times: i32) {    // 定义可传入的参数println!("赚钱{}次", times);
}

在函数签名当中,需要显式声明每个参数的类型(Rust的设计者慎重考虑的结果),以便于编译器根据其他部分的代码进行推导后能明确意图,显式地标准总好过复杂的外部情形,对吧?

而对于需要传入多个函数参数的场景,参数彼此直接使用,间隔开即可

fn main() { make_money(3, 100);
}
// 多个参数,指出类型,“,”分隔
fn make_money(times: i32, value: i32) {println!("赚钱{}次, 每次{}", times, value);
}

函数中的语句和表达式

先来了解下两个概念:语句和表达式

  • 语句是执行操作但是不返回值的指令
  • 表达式是会进行计算并且得到一个值作为结果的指令

维基百科:语句&语句与表达式的区别

这样看来,表达式最终还是可以换成某个变量表示的,就像数学计算里一样,我们列了一长串计算的式子,最终的目的也只是为了一个计算结果
在这里插入图片描述
图中绿框的部分是语句,因为它们没有返回值,只是在描述一步步地操作,但是第二条语句的右侧红框部分是一条表达式,描述了sentence变量与234比较的结果,最终返回了bool类型

let sentence = 125;let result = {let temp = sentence / 2 ;temp == 234   // 没有分号,用作表达式返回
};

还有些复杂些的场景(比如套{}的多行语句),在末尾使用表达式,不带分号可以返回结果,因为表达式不包括分号的部分

1.3、函数返回值

函数的返回值也是签名的一部分,可以向调用者返回值,使用->表示,并在其后面声明其类型

可以使用return直接返回值或者函数体中最后一个表达式的值进行返回

fn sum(a: i32, b: i32) -> i32 {   // 定义类型a + b   // 表达式返回
}
let result = sum(3, 2);  // 返回5
println!("result={}", result);

如果为函数的表达式结果加上分号,那么就会变成语句,进而无法匹配返回值类型

在这里插入图片描述

在这里插入图片描述
可以从报错信息中看出,此时返回值类型不匹配,现在改成语句后编译器接收到的是(),似乎是空元组,那么其实也可以推测出语句默认返回的值就是空元组了,这正好对应了没有返回值的函数,其实它们的返回值()只是没有体现在代码中

在这里插入图片描述
如果体现出来,可以写成这样,没有返回值的函数其实也是隐含了一个类型的

2、控制流

程序往往不是平铺直叙的,需要包含循环、判断等控制逻辑使其更加丰满

2.1、if 表达式

if表达式主要是根据条件选择分支,许多的编程语言中都有类似的表达

let assets = 100;
if assets < 100 {  // 条件分支println!("穷人")
} else if assets >= 100 && assets < 10_000 {println!("普通工薪阶级")
} else {    // 兜底println!("大佬")
}

if会计算对应分支的条件表达式的bool值,为true则执行对应的代码块的内容,为false则将跳过整个代码块(Rust不会尝试将非布尔类型的值转换为布尔类型
并且,else ifelse总是伴随if,一同组成多条件的分支

接下来,还是需要继续强调一下if表达式作为表达式的属性,由于if其实是表达式,那么本身能够返回值,因此可以直接将if的整体判断和返回内容一同放置到值的位置上

let assets = 100;
let identity = if assets < 100 {    // 表达式作为右值"穷人"   // 返回值
} else if assets >= 100 && assets < 10_000 {  "普通工薪阶级"
} else {"大佬"
};
println!("身份={}", identity);    

这里对于原来的内容进行了改写,将if判断结构直接作为赋值语句的右值使用

需要注意的一点是,在使用if对于条件进行判断的时候,要确保所有分支返回的类型要统一
Rust编译器需要在编译的时候确认分支返回的类型,需要是某个确定的类型
在这里插入图片描述
在这里插入图片描述
上图这种就是一个返回了字符串字面量,而另一个分支是一个整数,显然不好确定嘛

2.2、循环

计算机很擅长做重复的工作,并且这样的工作也非常适合它们

在各种编程语言中,提供的循环的结构也都大同小异,Rust也是基于这些原型进行一些优化和改造

Rust提供了3种循环:

  • loop
  • while
  • for
2.2.1、loop循环

使用loop{}可以定义一段无限循环

loop {print!("放我出去!")
}

但是,通常我们不会进行无意义的无限循环,还是需要满足一定的条件的时候让它处理一些事情,这个时候就需要使用break跳出

let mut i = 1;
let result = loop {i += 1;if i % 3 == 1 {break i;   // 满足条件结束并返回 4}
};
println!("result={}", result);
2.2.2、while循环

while循环会在每次执行循环体之前判断一次条件,条件为true就执行,否则就跳出

let mut num = 10;
while num > 0 {println!("倒数={}", num);num -= 1;
}

在这里插入图片描述

2.2.3、for循环

使用for最大的好处是可以方便地遍历数组、元组等容器里的元素

let teams = ["姆巴佩", "哈兰德", "克瓦拉茨赫利亚", "贝林厄姆", "穆德里克"];
println!("开始点名!");
for player in teams.iter() {println!("{}", player);
}

在这里插入图片描述

在遍历元素方面,for显得更加安全简洁

for i in 0 .. teams.len() {   // 也可以使用Range通过区间取出索引println!("{}", i);
}

https://kaisery.github.io/trpl-zh-cn/ch03-05-control-flow.html

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

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

相关文章

深入了解IPv6——光猫相关设定:DNS来源、DHCPv6服务、前缀来源等

光猫IPv6设置后的效果对比图&#xff1a; 修改前&#xff1a; 修改后&#xff1a; 一、DNS来源 1. 网络连接 来源&#xff1a; 从上游网络&#xff08;如运营商&#xff09;获取 IPv6 DNS 信息&#xff0c;通过 PPPoE 或 DHCPv6 下发。 特点&#xff1a; DNS 服务器地址直…

【Vue3】前端使用 FFmpeg.wasm 完成用户视频录制,并对视频进行压缩处理

强烈推荐这篇博客&#xff01;非常全面的一篇文章&#xff0c;本文是对该博客的简要概括和补充&#xff0c;在不同技术栈中提供一种可行思路&#xff0c;可先阅读该篇文章再阅读本篇&#xff1a; FFmpeg——在Vue项目中使用FFmpeg&#xff08;安装、配置、使用、SharedArrayBu…

聊一下前端常见的图片格式

1. JPEG (JPG) 概述&#xff1a;是一种有损压缩的图像格式&#xff0c;它通过去除图像中一些人类视觉不易察觉的细节来减小文件大小。它支持数百万种颜色&#xff0c;能够很好地呈现照片等色彩丰富的图像内容。优点&#xff1a; 压缩率高&#xff1a;可以在保持相对较好的图像…

【数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;实现快速排序算法。 测试说明 平台会对你编写的代码进行测试&#xff1a; 测试输入示例&#xff1a; 10 6 8 7 9 0 1 3 2 4 5 (说明&#xff1a;第一行是元素个数&a…

企业级包管理器之 monorepomultirepo (8)

在企业级项目开发中&#xff0c;面对多个项目的管理&#xff0c;monorepo 和 multirepo 是两种常见的代码管理方案&#xff0c;它们各有特点与优劣&#xff0c;下面我们来详细了解一下。 一、基本概念 monorepo&#xff1a;“mono”在英语中有“单一的、单独的”之意&#xf…

【electron】electron forge + vite + vue + electron-release-server 自动更新客户端

基本信息 electron forge vue页面&#xff08;中文&#xff09;&#xff1a;https://forge.electron.js.cn/guides/framework-integration/vue-3 electron forge vue页面&#xff08;英文&#xff0c;中文版下面的tab无法点击&#xff09;&#xff1a;https://www.electronfor…

后端-带有多个动态查询条件的分页查询

page和pagesize是分页插件所带的参数&#xff0c;其他三个是模糊查询的条件字段 因为是路径动态&#xff1f;拼接 的形式&#xff0c;所以不需要注解requestbody&#xff0c;先封装到pageresult中&#xff0c;再把pageresult封装到result中。 后端给前端的返回值封装到Vo中

【机器学习算法】——决策树之集成学习:Bagging、Adaboost、Xgboost、RandomForest、XGBoost

集成学习 **集成学习(Ensemble learning)**是机器学习中近年来的一大热门领域。其中的集成方法是用多种学习方法的组合来获取比原方法更优的结果。 使用于组合的算法是弱学习算法&#xff0c;即分类正确率仅比随机猜测略高的学习算法&#xff0c;但是组合之后的效果仍可能高于…

Java常用 Date 时间格式化、Calender日历、正则表达式的用法

目录 1. SimpleDateFormat 日期格式化类 1.1 Date 类型转 String 1.2 String 类型转 Date 2. Calendar 日历类 3. 正则表达式 3.1 正则表达式的组成部分 3.2 手机号正则表达式 3.3 常用密码校验正则表达式 1. SimpleDateFormat 日期格式化类 SimpleDateFormat 是Java中…

jdk1.8安装及环境配置(最新最详细教学!!!)

jdk1.8安装&#xff1a; 看了网上很多关于jdk1.8的安装&#xff0c;我觉得有时候会让人云里雾里&#xff0c;虽然自己可能配置成功&#xff0c;不过没有一套自己的思路&#xff0c;我结合自己的经验来说一下。 jdk在windows有两种安装方式&#xff0c;一种是解压缩包&#xf…

51c嵌入式~单片机~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/12362395 一、不同的电平信号的MCU怎么通信&#xff1f; 下面这个“电平转换”电路&#xff0c;理解后令人心情愉快。电路设计其实也可以很有趣。 先说一说这个电路的用途&#xff1a;当两个MCU在不同的工作电压下工作&a…

httpsok-v1.18.0-SSL证书自动续期

&#x1f525;httpsok-v1.18.0-SSL证书自动续期 介绍 httpsok 是一个便捷的 HTTPS 证书自动续期工具&#xff0c;基于全新的设计理念&#xff0c;专为 Nginx 、OpenResty、Apache 等服务器设计。已服务众多中小企业&#xff0c;稳定、安全、可靠。 一行命令&#xff0c;一分…

Dynamics 365 CRM- 后端

Dynamics 365 CRM 后端插件语法示例 public IPluginExecutionContext context null;//上下文 public IOrganizationServiceFactory serviceFactory null;//组织服务工厂对象 public IOrganizationService service null;//Org服务对象//创建执行上下文 context (IPluginExe…

Linux驱动开发(12):中断子系统–按键中断实验

本章我们以按键为例讲解在驱动程序中如何使用中断&#xff0c; 在学习本章之前建议先回顾一下关于中断相关的裸机部分相关章节&#xff0c; 这里主要介绍在驱动中如何使用中断&#xff0c;对于中断的概念及GIC中断控制器相关内容不再进行讲解。 本章配套源码和设备树插件位于“…

Grafana配置告警规则推送企微机器人服务器资源告警

前提 已经部署Grafana&#xff0c;并且dashboard接入数据 大屏编号地址&#xff1a;Node Exporter Full | Grafana Labs 创建企微机器人 备注&#xff1a;群里若有第三方外部人员不能创建 机器人创建完成&#xff0c;记录下来Webhook地址 Grafana配置告警消息模板 {{ define &…

[WiFi] WiFi安全加密WEP Vs WPA Vs WPA2 Vs WPA3整理

WiFi安全标准时间线 WEP&#xff08;Wired Equivalent Privacy&#xff09; WEP最早于1997年推出&#xff0c;是为了保护无线网络上的数据通信而设计的。当时&#xff0c;Wi-Fi技术还处于起步阶段&#xff0c;人们开始意识到需要一种安全协议来防止未经授权的访问和窃听。WEP被…

使用Keil V6编译 FreeRTOS CMSIS V2版本 ETH + Lwip 编译报错问题解决方式

网上其他人写的都解决不了&#xff0c;要不用的是CMSIS V1版本&#xff0c;根据他们的方式搞完还是报错&#xff0c;今天花点时间自己搞一下。 不想自己动手&#xff1f;没问题&#xff0c;模版已上传Gitee https://gitee.com/maybe_404/stm32-f4xx_-free-rtos_-lwip_-templa…

群控系统服务端开发模式-应用开发-操作记录功能开发

一、开放路由 在根目录下route文件夹下修改app.php文件&#xff0c;代码如下&#xff1a; // 操作日志Route::get(token/get_list,permission.Token/getList);// 获取操作日志列表Route::post(token/get_all,permission.Token/getAll);// 获取操作日志所有数据Route::post(toke…

大模型闯关学习——L1G6000 OpenCompass 评测书生大模型实践

任务要求&#xff1a; 基础任务&#xff1a; 首先创建开发机 进入开发机&#xff1a; 创建测评所需要的环境 conda create -n opencompass python3.10 conda activate opencompass cd /root git clone -b 0.3.3 https://github.com/open-compass/opencompass cd opencompas…

C# 探险之旅:第三十节 - 类型class(继承Inheritance) —— 当“儿子”继承“老爸”的遗产

嘿&#xff0c;探险家们&#xff01;欢迎再次踏上我们的C#奇幻旅程。今天&#xff0c;我们要聊一个既有趣又实用的话题——继承&#xff08;Inheritance&#xff09;&#xff01;想象一下&#xff0c;如果你的“儿子”能够继承“老爸”的遗产&#xff0c;那编程世界里的对象们也…