Rust 探索(三)—— 通用编程概念(下)
Rust 探索(三)—— 通用编程概念(下)
上篇主要是关于类型、变量等内容的介绍,如果已经学习过其他编程语言,那么这一块并不会有太大难度,或许仅仅是一些关键字的替换
而且,在了解其中的一些概念的时候,似乎还隐隐约约能够看到一些接触过的其他编程语言的影子,就比如说元组、列表的概念与Python如出一辙,解构赋值的写法让我想到了TypeScript,区分可变、不可变变量以及类型推导的特性又让我联想到Kotlin,或许Rust也有不断地借鉴其他语言设计的优秀之处吧,亦或是这正是代表了语言演进的方向
¶1. 函数
函数用来对功能逻辑进行封装,能够增强复用、提高代码的可读
在Rust中,函数通过fn
关键字进行声明,并且函数的名称遵循蛇形命名法,即名称使用小写字母进行组合,单词与单词之间使用下划线进行分割,这点倒是和Python中的函数命名相一致
1 | fn make_money() { // 蛇形命名法 |
函数名后面的括号放置参数列表、花括号中编写具体的业务逻辑,这些算得上行业通用了
函数可以先定义或后定义,只要对于使用区域可见即可
1 | fn main() { |
¶1.1. 函数参数
函数的参数可以将外部的变化灵活地告诉内部的逻辑,在框架不变的前提下随机应变,作为函数签名的一部分,就像在文档上看到的那样
1 | fn main() { |
定义参数的目的是为了外界能够给它传值,就好像坐公交车一样,投币口是参数列表,有一个参数,是硬币(让你投的),当外界传值时(投币),根据你的输入执行(让你上车)
在函数签名当中,需要显式声明每个参数的类型(Rust的设计者慎重考虑的结果),以免编译器根据其他部分的代码进行推导后能明确意图,显式地标准总好过复杂的外部情形,对吧?
1 | fn main() { |
¶1.2. 函数体中的语句和表达式
函数体,也就是先前{}
包裹的部分,其中有若干条语句组成,并且可以以一条表达式作为结尾
¶1.2.1. 语句 vs 表达式
语句是执行操作但是不返回值的指令
表达式是会进行计算并且得到一个值作为结果的指令
绿框的部分是语句,因为它们没有返回值,只是在描述一步步地操作,但是第二条语句的右侧红框部分是一条表达式,描述了sentence变量与234比较的结果,返回了bool类型
1 | let sentence = 125; |
复杂些的场景(比如套{}
的多行语句),在末尾使用表达式,不带分号可以返回结果
¶1.3. 函数的返回值
函数的返回值也是签名的一部分,可以向调用者返回值,使用->
,并在其后面声明其类型
1 | fn sum(a: i32, b: i32) -> i32 { // 定义类型 |
1 | let result = sum(3, 2); // 返回5 |
如果为函数的表达式结果加上分号,那么就会编程语句,进而无法匹配返回值类型
除了使用表达式作为最后的返回,也可以采用return
返回
1 | fn sum(a: i32, b: i32) -> i32 { |
¶2. 注释
注释的主要作用是用于说明代码的逻辑和功能,便于自己和一起写代码其他人理解,增强代码的可读性
编译器会自动忽略注释,通常单行注释使用//
1 | // 计算求和 |
而多行注释则是单行注释的复制,在每行前面加上//
1 | // 计算 |
¶3. 控制流
程序往往不是平铺直叙的,需要包含循环、判断等控制逻辑使其更加丰满
¶3.1. if表达式
if
表达式主要是根据条件选择分支,许多的编程语言中都有类似的表达
1 | let assets = 100; |
if
会计算对应分支的条件表达式的bool值,为true则执行对应的代码块的内容,为false则将跳过整个代码块(Rust不会尝试将非布尔类型的值转换为布尔类型)
并且,else if
和else
总是伴随if
,一同组成多条件的分支
¶3.1.1. 表达式
由于if
其实是表达式,那么本身能够返回值,因此可以直接将if
的整体判断和返回内容一同放置到值的位置上
1 | let assets = 100; |
所有分支返回的类型必须统一
编译器会对分支进行检查,以免类型无法匹配
¶3.2. 循环
计算机很擅长做重复的工作,并且这样的工作也非常适合它们
在各种编程语言中,提供的循环的结构也都大同小异,Rust也是基于这些原型进行一些优化和改造
Rust提供了3种循环:
- loop
- while
- for
¶3.2.1. loop循环
使用loop{}
可以定义一段无限循环
1 | loop { |
但是,通常我们不会进行无意义的无限循环,还是需要满足一定的条件的时候让它处理一些事情,这个时候就需要使用break
跳出
1 | let mut i = 1; |
¶3.2.2. while条件循环
while
循环会在每次执行循环体之前判断一次条件,条件为true就执行,否则就跳出
1 | let mut num = 10; |
¶3.2.3. for循环
使用for
最大的好处是可以方便地遍历数组、元组等容器里的元素
1 | let teams = ["姆巴佩", "哈兰德", "克瓦拉茨赫利亚", "贝林厄姆", "穆德里克"]; |
在遍历元素方面,for
显得更加安全简捷
1 | for i in 0 .. teams.len() { // 也可以使用Range通过区间取出索引 |