Rust 学习 03

archive time: 2021-08-24

现在开始跟随杨旭大佬的视频开始学习 Rust,进度一致

由于我手上的这本书是英文的,太累了,还是看视频比较快,所以今天开始我就根据 杨旭大佬的 rust 视频 开始学 Rust,进度紧跟上一期博客,来看看 Rust 中的变量类型

标量类型

Rust 中,每个值都有一个确定的类型,根据每个类型,Rust 有不同的方式来处理这个值

一般而言,Rust 的编辑器可以自动推断出变量的类型,所以一般不需要标出类型,但是有时候需要我们手动标明变量的类型,例如

fn main() {
    let guess = match "42".parse::<u32>() {
        Ok(num) => num,
        Err(_) => {
            println!("数据转换失败!");
            0
        }
    }
}

这里 parse() 就要求我们给出具体的数据类型

parse can parse any type that implements the FromStr trait

所谓的标量类型,就是一个单个的值对应的类型,常见的有 整数类型, 浮点类型, 布尔类型, 字符类型

整数类型

Rust 中类型有很多,整数类就有诸如 i8, u32, i64 等等,从 8128 以及 arch,分别有有符号和无符号两种,共计 12 种 整数类型,日常,i32u32 就足够了

arch 对应的是 isizeusize 两种,与程序运行的计算机的架构相关,如果是 32 位计算机,那就等同于 i32u32

数据的范围,有符号的为,而无符号的则是

整数字面值

一般而言,整数可以用一下方式表示

字面值类型例子
十进制98_222
十六进制0xfff
八进制0o777
二进制0b1111_0000
字节 (仅 u8 类型)b’A’

要注意,字节类型只能是 u8 类型,还要注意,数字间可以使用下划线 _ 来隔开,增加可读性

除了字节字面量外,都可以使用类型后缀来表明类型,例如 67u8,整数类型的默认类型是 i32

整数溢出

Rust 对于不同模式下的溢出有不一样的处理方式,在 Debug 模式下,也就是默认模式下,整数类型的溢出会导致 Rust 程序返回 panic 导致程序报错后强制结束

而对于发布 (release) 模式,也就是编译时使用 --release 选项,Rust 对于整数溢出会使用 环绕 处理,即对于 u8 类型,256 会变成 0,而 257 会变成 1

浮点类型

浮点数有两种基本类型,f32f64,默认是 f64

let some_float = 64.9f32;

布尔类型

布尔类型就只有两个值,truefalse,分别占用一个字节大小,符号是 bool

let t = true;
let f: bool = false;

字符类型

字符类型占用 4 个字符,默认 utf8 字符集,字面值使用单引号表示

let z: char = '🎂'

复合类型

复合类型就是多个值的类型,Rust 中的基础复合类型就是 ArrayTuple

元组

元组可以存储多个类的多个值,创建 Tuple 可以使用圆括号创建

let tup: (u32, f32, u8) = (500, 5.4, 1);
println!("{}, {}, {}", tup.0, tup.1, tup.2);

元组可以通过点来取值,从 0 开始计数,我们还可以通过模式匹配来解构 (destructure) 提取值

let tup: (u32, f32, u8) = (500, 5.4, 1);
let (x, y, z) = tup;
println!("{}, {}, {}", x, y, z);

但是 rust 中元组里的值是可以修改的,如果你的元组的定义是 mut 的话

fn main() {
    let mut tup = ("hello", 12, 'k');
    tup.1 = 10;
    println!("{}, {}, {}", tup.0, tup.1, tup.2);
}

输出如下

hello, 10, k

数组

数组相较于元组,数组的元素类型必须要一致,而且长度也是不可变的

let arr = [1, 2, 3, 4, 5];

如果你想使你的数据存在栈内存,而非堆内存上,可以使用数组,或者保证有固定数量的元素,也可以使用数组

类似的类型还有 VectorVector 比数组灵活,而且 Vector 长度可变,如果不确定应该是使用数组还是向量,那就尽量使用 Vector

数组类型使用 [type : length] 表示,例如 [i32 : 4]

还可以使用 [default ; length] 的方式来表示一个 length 长度的全是 default 的数组,例如 let a = [3 ; 3],这里 a 就表示 [3, 3, 3] 这样一个数组

访问数组元素

数组是在上分配的单个块的内存,可以使用索引来访问数组元素

let fst = a[0];
let sec = a[0];

如果访问索引超出数组边界,如果这种越界并不 显然,这时候编译时并不会报错,但是运行时会出现数组越界的错误,panic 结束程序

let index = [13, 14, 15];
let nums = [1; 12];
// 编译时不会报错
println!("{}", num[index[0]]);

函数

函数可以使用 fn 关键字来定义,默认使用蛇形命名法,都是小写,通过下划线分隔

fn say_hello() {
    println!("hello");
}

此函数的返回值是一个特殊值 unit ()

如果带参数,可以通过签名来定义,函数返回值类型需要使用 -> 来表示

fn add2(x: i32) -> i32 {
    return x + 2;
}

默认最后一个表达式的值就是函数的值

fn five() -> i32 {
    5
}

注释

Rust 里注释和 C 类似,可以通过 ///* */ 来表示


好,今天的笔记到此结束