Rust 数据类型

  |   0 评论   |   0 浏览

Rust 是静态类型语言,它的数据类型分为两类:标量(scalar)类型和复合(compound)类型。

标量类型

标量(scalar)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。

整型

Rust 提供了不同长度的整型,并且每种长度的整型都分为有符号和无符号两类。

整型分类:

长度 有符号 无符号 备注
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
arch isize usize 类型长度依赖计算机架构,64 位架构上它是 64 位,32 位架构它是 32 位。

有符号类型值的范围是:-(2^{n-1})2^{n-1} -1 ,并且以补码形式进行存储。
无符号类型值的范围是:0 到 2^n - 1

整型字面量:

整型字面量 示例 说明
Decimal (十进制) 98_222 无前缀
Hex (十六进制) 0xff 前缀是:0x
Octal (八进制) 0o77 前缀是:0o
Binary (二进制) 0b1111_0000 前缀是:0b
Byte (单字节字符)(仅限于 u8) b'A' 前缀是:b

在整型字面量中,Rust 允许使用 _ 做为分隔符以方便读数。整型字面量默认的数据类型是:i32。若要使用其他类型,则需要使用类型后缀进行指定,比如:57u8(Byte 字面量除外)。

浮点型

Rust 也有两个原生的 浮点数(floating-point numbers)类型,它们是带小数点的数字。Rust 的浮点数类型是 f32f64,分别占 32 位和 64 位。默认类型是 f64,因为在现代 CPU 中,它与 f32 速度几乎一样,不过精度更高。

布尔类型

Rust 中的布尔类型有两个可能的值:truefalse,Rust 中的布尔类型使用 bool 表示。

字符类型

Rust 的 char 类型的大小为四个字节(four bytes),并代表了一个 Unicode 标量值(Unicode Scalar Value)。字符类型字面量使用单引号指定。

复合类型

复合类型(Compound types)不是单一的值,它由多个值组合而成。Rust 有两个原生的复合类型:元组(tuple)和数组(array)。

元组

元组的特点:

  • 可以包含不同类型的值;
  • 长度固定,一旦声明,不能更改。

示例:

 1fn main() {
 2    // 使用括号和括号内用逗号分隔的值表示元组
 3    let tup: (i32, f64, u8) = (500, 6.4, 1);
 4
 5    // 将 tup 解构为三个不同的变量
 6    let (x, y, z) = tup;
 7    println!("The value of y is: {}", y);
 8
 9    // 可以使用点号(.)后跟值的索引来直接访问
10    println!("The value of tup.0 is: {}", tup.0);
11}

数组

数组的特点:

  • 数组元素的类型必须相同;
  • 长度固定,一旦声明,不能更改;
  • 在内存中是连续存储的。

示例:

1fn main() {
2    // 指定元素类型和数组长度
3    let arr1: [i32; 5] = [1, 2, 3, 4, 5];
4    println!("arr1[0] = {}", arr1[0]);
5
6    // 指定初始值和数组长度
7    let arr2 = [3; 5];
8    println!("arr2[1] = {}", arr2[1]);
9}

集合类型

Rust 标准库提供了一系列的集合类型。不同于内建的数组和元组类型,这些集合指向的数据是储存在堆上的,这意味着数据的数量不必在编译时就已知,并且还可以随着程序的运行增长或缩小。

在 Rust 中,集合可以被分为以下四类:

  • Sequences: Vec, VecDeque, LinkedList
  • Maps: HashMap, BTreeMap
  • Sets: HashSet, BTreeSet
  • Misc: BinaryHeap

在 Rust 程序中常用的集合:

  • vector —— 按顺序储存一系列数量可变的值。
  • 字符串(string)—— 是字符的集合。
  • 哈希 map(hash map)—— 键-值对的集合。

vector

只能存放相同类型的值,支持泛型。

新建 vector

1// 新建一个空的 vector
2let v: Vec<i32> = Vec::new();
3// 使用 vec! 宏创建一个包含初值的 vector
4let v = vec![1, 2, 3];

修改 vector

1// 新增元素
2let mut v = Vec::new();
3
4v.push(5);
5v.push(6);
6v.push(7);
7v.push(8);

读取 vector 元素

 1let v = vec![1, 2, 3, 4, 5];
 2
 3// 通过索引访问,索引从0开始
 4let third: &i32 = &v[2];
 5println!("The third element is {}", third);
 6
 7// 使用get方法
 8match v.get(2) {
 9    Some(third) => println!("The third element is {}", third),
10    None => println!("There is no third element."),
11}

遍历 vector 中的元素

1let v = vec![100, 32, 57];
2for i in &v {
3    println!("{}", i);
4}

字符串

称作 String 的类型是由标准库提供的,而没有写进核心语言部分,它是可增长的、可变的、有所有权的、UTF-8 编码的字符串类型。
String 是对 Vec<u8> 的封装。

新建字符串

 1// 新建一个空的字符串
 2let mut s = String::new();
 3
 4// 从字符串字面值创建 String
 5let data = "initial contents";
 6let s = data.to_string();
 7let s = "initial contents".to_string();
 8
 9// 使用 String::from 函数从字符串字面值创建 String
10let s = String::from("initial contents");

修改字符串

 1// 使用 push_str 方法向 String 附加字符串 slice
 2let mut s = String::from("foo");
 3s.push_str("bar");
 4
 5// 使用 push 将一个字符加入 String 值中
 6let mut s = String::from("lo");
 7s.push('l');
 8
 9// 使用 + 运算符将两个 String 值合并到一个新的 String 值中
10let s1 = String::from("Hello, ");
11let s2 = String::from("world!");
12let s3 = s1 + &s2; // 注意 s1 被移动了,不能继续使用
13
14// 使用 format! 宏拼接字符串
15let s1 = String::from("tic");
16let s2 = String::from("tac");
17let s3 = String::from("toe");
18
19let s = format!("{}-{}-{}", s1, s2, s3);

字符串遍历

1// 基于 Unicode 标量值,遍历字符
2for c in "नमस्ते".chars() {
3    println!("{}", c);
4}
5
6// 遍历所有字节
7for b in "नमस्ते".bytes() {
8    println!("{}", b);
9}

从字符串中获取字形簇是很复杂的,所以标准库并没有提供这个功能。crates.io 上有些提供这样功能的 crate。

哈希 Map

HashMap<K, V>同样支持泛型。

新建

 1use std::collections::HashMap;
 2
 3// 新建一个哈希 map 并插入一些键值对
 4let mut scores = HashMap::new();
 5scores.insert(String::from("Blue"), 10);
 6scores.insert(String::from("Yellow"), 50);
 7
 8// 用队伍列表和分数列表创建哈希 map
 9let teams = vec![String::from("Blue"), String::from("Yellow")];
10let initial_scores = vec![10, 50];
11let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();

访问

 1// 访问哈希 map 中储存的蓝队分数
 2use std::collections::HashMap;
 3
 4let mut scores = HashMap::new();
 5
 6scores.insert(String::from("Blue"), 10);
 7scores.insert(String::from("Yellow"), 50);
 8
 9let team_name = String::from("Blue");
10let score = scores.get(&team_name);
11println!("Blue: {}", score.unwrap());
12
13// for 循环遍历哈希map中的键值对
14for (key, value) in &scores {
15    println!("{}: {}", key, value);
16}

更新

 1let mut scores = HashMap::new();
 2
 3// 覆盖特定键对应的值
 4scores.insert(String::from("Blue"), 10);
 5scores.insert(String::from("Blue"), 25);
 6
 7println!("{:?}", scores);
 8
 9// 使用 entry 方法只在键没有对应一个值时插入
10scores.entry(String::from("Yellow")).or_insert(50);
11scores.entry(String::from("Blue")).or_insert(50);
12
13println!("{:?}", scores);
14
15// 通过哈希 map 储存单词和计数来统计出现次数
16let text = "hello world wonderful world";
17
18let mut map = HashMap::new();
19
20for word in text.split_whitespace() {
21    let count = map.entry(word).or_insert(0);
22    *count += 1;
23}
24
25println!("{:?}", map);

相关资料

Rust 程序设计语言
Module std::collections