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

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

1、函数

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

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

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

1.1、函数名称

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

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

维基百科:蛇形命名法

rust 复制代码
fn make_money() {   // 蛇形命名法
    println!("赚钱");
}

fn main() {   // 作为入口的main()函数
    // 函数调用,函数名加(参数),现在没有参数就是()
    make_money();  
}

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

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

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

1.2、函数参数

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

rust 复制代码
fn main() {
    make_money(3);     // 传入具体的参数
}

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

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

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

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

函数中的语句和表达式

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

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

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

这样看来,表达式最终还是可以换成某个变量表示的,就像数学计算里一样,我们列了一长串计算的式子,最终的目的也只是为了一个计算结果

图中绿框的部分是语句,因为它们没有返回值,只是在描述一步步地操作,但是第二条语句的右侧红框部分是一条表达式,描述了sentence变量与234比较的结果,最终返回了bool类型

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

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

1.3、函数返回值

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

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

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

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

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

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

2、控制流

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

2.1、if 表达式

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

rust 复制代码
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的整体判断和返回内容一同放置到值的位置上

rust 复制代码
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{}可以定义一段无限循环

rust 复制代码
loop {
    print!("放我出去!")
}

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

rust 复制代码
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就执行,否则就跳出

rust 复制代码
let mut num = 10;
while num > 0 {
	println!("倒数={}", num);
	num -= 1;
}
2.2.3、for循环

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

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

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

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

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

相关推荐
dal118网工任子仪几秒前
66,【6】buuctf web [HarekazeCTF2019]Avatar Uploader 1
笔记·学习
02苏_6 分钟前
2025/1/21 学习Vue的第四天
学习
羊小猪~~29 分钟前
MYSQL学习笔记(四):多表关系、多表查询(交叉连接、内连接、外连接、自连接)、七种JSONS、集合
数据库·笔记·后端·sql·学习·mysql·考研
约定Da于配置31 分钟前
uniapp封装websocket
前端·javascript·vue.js·websocket·网络协议·学习·uni-app
东京老树根2 小时前
Excel 技巧15 - 在Excel中抠图头像,换背景色(★★)
笔记·学习·excel
ByteBlossom6662 小时前
MDX语言的语法糖
开发语言·后端·golang
Ronin-Lotus3 小时前
嵌入式硬件篇---ADC模拟-数字转换
笔记·stm32·单片机·嵌入式硬件·学习·低代码·模块测试
编程小猹3 小时前
学习golang语言时遇到的难点语法
学习·golang·xcode
肖田变强不变秃4 小时前
C++实现矩阵Matrix类 实现基本运算
开发语言·c++·matlab·矩阵·有限元·ansys
promising-w4 小时前
单片机基础模块学习——数码管
单片机·嵌入式硬件·学习