Rust 第三节 - 通用编程概念

3 通用编程概念

3.1 变量

在rust中我们声明一个变量使用let,例如:

rust 复制代码
let x: i8 = 1;

rust变量命名规范 使用蛇形命名法, 如snake_name,例如:

rust 复制代码
let my_name: &str = "stephen"

当我们声明了一个字符串变量,但是我想不改变变量名的情况下,重新声明一个数字类型,这时候我们可以使用rust变量变量遮蔽的特性,例如:

rust 复制代码
let x: i8 = 1;
let x: &str = "stephen"

当我们不需要更换类型,我们只需要在let后面加上一个可变mut符修复,表明当前的变量可以修改,例如:

rust 复制代码
let mut x: i8 = 1;

3.2 常量

在rust中,我们声明一个常量使用const关键字,并且命名使用大写蛇形命名法,例如:

rust 复制代码
const MY_NAME: &str = "stephen"

我们使用const声明的变量不能再此修改,否则会编译错误。

3.3 数据类型

3.3.1 标量数据类型

标量分为:

  1. 整数
  2. 浮点数
  3. 布尔值
  4. 字符串
3.3.1.1 整数

整数分为带符号不带符号的整数,我们使用i开头表示带正负号,u开头表示不带符号(表示正数),例如:

rust 复制代码
let with_symbol: i32 = -1; // rust默认推导出类型为i32
let without_symbol: u32 = 1;

带符号不带符号的整数的长度类型各有6种,如下:

带符号 不带符号
i8 u8
i16 i16
i32 u32
i64 u64
i128 u128
isize usize

其中i8u8分别表示的含义(下面的n,表示n次方),如下:

  • i8 表示该数字的范围在 -(2n - 1) ~ (2n - 1)之间,也就是-255 ~ 255之间
  • u8 表示该数字的范围在 0 ~ (2n - 1)之间,也就是 0 ~ 255之间

isizeusize 表示,如果系统的CPU是32位,则表示i32``u32,如果是64位,则表示i64``i64

3.3.1.2 浮点数

在rust中,我们用f表示声明的是一个浮点数变量,例如:

rust 复制代码
let float_number: f64 = 1.0;

浮点数有两种长度类型,f32f64,长度范围和整数一致。

补充:

  • 尽量不要长度越界 举个例子,当我们使用i8的长度类型,但是我实际的长度为256,这个时候会出现长度越界的情况,实际编码中避免出现这种问题。
3.3.1.3 布尔值

在rust中,我们声明一个布尔值如下:

rust 复制代码
let booleans: bool = false;

布尔值类型有两种值,true或者false

3.3.1.4 字符&字符串

在rust,我们使用单引号 ''声明一个字符:

rust 复制代码
let character: &str = 'a';

使用双引号 ""声明一个字符串字面量:

rust 复制代码
let strings: &str = "stephen"

当我们想声明一个动态长度的字符串怎么生成呢? 这时候我们需要使用Stringnew方法去生成(后面会详细讲到),使用String生成的字符串,会存储到堆中,并在栈中存储指向堆中的指针长度容量,例如:

rust 复制代码
let mut str: String = String::new();
str.push_str("hello")
str.push_str(", world")

3.3.2 复合数据类型

复合类型分为:

  1. 元组
  2. 数组
3.3.2.1 元祖

在rust中,我们创建一个元祖,使用(),元祖可以包含任意的数据类型,例如:

rust 复制代码
let tuple: (i32, &str) = (1, "stephen")

当我们需要元祖中某个数据项时,我们可以使用索引的方式,例如:

rust 复制代码
let tuple: (i32, &str) = (1, "stephen");
let first: i32 = tuple.0; // 1
let second: &str = tuple.1; // "stephen"

元祖的类型、长度是固定不变的,长度根据生成时决定,如果尝试修改会编译错误。但是可以使用变量的变量遮蔽去覆盖则不会报错。例如:

rust 复制代码
let tuple: (i32, String) = (1, String::new());
let tuple: (i32, i32) = (1, 1); // 正确编译

let mut tuple: (i32, String) = (1, String::new());
tuple: (i32, i32) = (1, 1); // 编译失败

当元祖没有数据时,也叫单元类型,当我们的函数没有返回时,其实返回的就是单元类型.

rust 复制代码
let unit_type:() = ();
3.3.2.2 数组

在rust中,我们创建一个数组,使用中括号[]数组只能存储相同类型,例如:

rust 复制代码
let mut arr: [i8; 2] = [1,2];

其中[i8;2]表示的含义是,第一个是你的数组每一项的类型,第二个表示数据的个数也就是数组的长度;

数组的长度是固定的,不能对其修改,否则会编译错误,例如:

rust 复制代码
let mut arr: [i8; 2] = [1, 2];
arr.push(2) // 编译出错

那如果我们想创建一个动态长度的数组呢?我们我们可以使用Vec结构上面的new方法来生成(后面会详细讲到),或者使用简单的方式,vec![],例如:

rust 复制代码
let mut arr: Vec<i32> = Vec::new(); // 不能初始化数据
arr.push(2) // 编译出错

let arr1: Vec<i32> = vec![1,2,3]; // 可以初始化数据

3.4 注释

在rust中,当我们需要注释的时候我们一般使用//后续会详细讲到

3.5 if 表达式

在rust中我们一般使用if来作为条件判断的一个表达式,例如:

rust 复制代码
let right: bool = true;
if right {
    print!("正确")
} else {
    print!("错误")
}

注意 我们放到if表达式中的right值必须保证是一个布尔值,否则会编译错误,因为它不会自动转化类型,例如:

rust 复制代码
let right: i32 = 1;
if right { // 编译错误
    print!("正确")
} else {
    print!("错误")
}

在rust中,if会有一个返回值,我们可以使用if进行条件判断,获取返回值进行后续操作,但是需要保证ifelse ifelse返回的数据类型相同,,例如:

rust 复制代码
let return_str: &str = if true { "right" } else { "wrong" };
print("{}", return_str)

并且这里我们可以使用"right"直接返回该值,非常方便。

这里强调一下,语句和表达式 ,在一个模块中,当我们没有使用;时,其实可以理解它就是一个表达式,它会返回该值。

3.6 循环

rust中的循环分为3种

  • loop
  • while
  • for

对于loop的使用,我们可以使用continue跳过当前循环,使用break打断当前循环,例如:

rust 复制代码
 let mut index = 0;
    loop {
        index = index + 1;
        if index == 3 {
            continue; //跳过
        }
        println!("{}", index);
        if index == 5 {
            break; // 打断
        }
    }

但是每次写break显得很多余,于是我们可以使用while循环来优化,例如:

rust 复制代码
let mut index = 0;
    while index < 5 {
        index += 1;
        if index == 3 {
            continue;
        }
        println!("{}", index);
    }

但是当我们循环遍历数组的时候,每次都要去处理这个index值,很麻烦也不好维护,于是我们使用第三种最常见的循环遍历方法,for循环,例如:

rust 复制代码
let arr: Vec<i32> = vec![1, 2, 3, 4, 5];
    for i in arr {
        if i == 3 {
            continue;
        }
        println!("{}", i)
    }
    println!("========:========");
    for i in 1..6 {
        if i == 3 {
            continue;
        }
        println!("{}", i)
    }

课后作业

  • 摄氏温度与华氏温度的相互转换。
  • 生成一个n阶的斐波那契数列。
  • 打印圣诞颂歌The Twelve Days of Christmas的歌词,并利用循环处理其中重复的内容。
相关推荐
coder_pig20 分钟前
跟🤡杰哥一起学Flutter (三十四、玩转Flutter手势✋)
前端·flutter·harmonyos
万少26 分钟前
01-自然壁纸实战教程-免费开放啦
前端
独立开阀者_FwtCoder28 分钟前
【Augment】 Augment技巧之 Rewrite Prompt(重写提示) 有神奇的魔法
前端·javascript·github
yuki_uix39 分钟前
AI辅助网页设计:从图片到代码的实践探索
前端
我想说一句39 分钟前
事件机制与委托:从冒泡捕获到高效编程的奇妙之旅
前端·javascript
陈随易40 分钟前
MoonBit助力前端开发,加密&性能两不误,斐波那契测试提高3-4倍
前端·后端·程序员
小飞悟1 小时前
你以为 React 的事件很简单?错了,它暗藏玄机!
前端·javascript·面试
中微子1 小时前
JavaScript 事件机制:捕获、冒泡与事件委托详解
前端·javascript
Whoisshutiao1 小时前
网安-XSS-pikachu
前端·安全·网络安全
惊鸿2871 小时前
Taro3+小程序Canvas动态生成海报和二维码分享到朋友圈
前端