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 的浮点数类型是 f32
和 f64
,分别占 32 位和 64 位。默认类型是 f64
,因为在现代 CPU 中,它与 f32
速度几乎一样,不过精度更高。
布尔类型
Rust 中的布尔类型有两个可能的值:true
和 false
,Rust 中的布尔类型使用 bool
表示。
字符类型
Rust 的 char 类型的大小为四个字节(four bytes),并代表了一个 Unicode 标量值(Unicode Scalar Value)。字符类型字面量使用单引号指定。
复合类型
复合类型(Compound types)不是单一的值,它由多个值组合而成。Rust 有两个原生的复合类型:元组(tuple)和数组(array)。
元组
元组的特点:
- 可以包含不同类型的值;
- 长度固定,一旦声明,不能更改。
示例:
fn main() {
// 使用括号和括号内用逗号分隔的值表示元组
let tup: (i32, f64, u8) = (500, 6.4, 1);
// 将 tup 解构为三个不同的变量
let (x, y, z) = tup;
println!("The value of y is: {}", y);
// 可以使用点号(.)后跟值的索引来直接访问
println!("The value of tup.0 is: {}", tup.0);
}
数组
数组的特点:
- 数组元素的类型必须相同;
- 长度固定,一旦声明,不能更改;
- 在内存中是连续存储的。
示例:
fn main() {
// 指定元素类型和数组长度
let arr1: [i32; 5] = [1, 2, 3, 4, 5];
println!("arr1[0] = {}", arr1[0]);
// 指定初始值和数组长度
let arr2 = [3; 5];
println!("arr2[1] = {}", arr2[1]);
}
集合类型
Rust 标准库提供了一系列的集合类型。不同于内建的数组和元组类型,这些集合指向的数据是储存在堆上的,这意味着数据的数量不必在编译时就已知,并且还可以随着程序的运行增长或缩小。
在 Rust 中,集合可以被分为以下四类:
- Sequences: Vec, VecDeque, LinkedList
- Maps: HashMap, BTreeMap
- Sets: HashSet, BTreeSet
- Misc: BinaryHeap
在 Rust 程序中常用的集合:
- vector —— 按顺序储存一系列数量可变的值。
- 字符串(string)—— 是字符的集合。
- 哈希 map(hash map)—— 键-值对的集合。
vector
只能存放相同类型的值,支持泛型。
新建 vector
// 新建一个空的 vector
let v: Vec<i32> = Vec::new();
// 使用 vec! 宏创建一个包含初值的 vector
let v = vec![1, 2, 3];
修改 vector
// 新增元素
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
v.push(8);
读取 vector 元素
let v = vec![1, 2, 3, 4, 5];
// 通过索引访问,索引从0开始
let third: &i32 = &v[2];
println!("The third element is {}", third);
// 使用get方法
match v.get(2) {
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}
遍历 vector 中的元素
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);
}
字符串
称作 String
的类型是由标准库提供的,而没有写进核心语言部分,它是可增长的、可变的、有所有权的、UTF-8
编码的字符串类型。
String
是对 Vec<u8>
的封装。
新建字符串
// 新建一个空的字符串
let mut s = String::new();
// 从字符串字面值创建 String
let data = "initial contents";
let s = data.to_string();
let s = "initial contents".to_string();
// 使用 String::from 函数从字符串字面值创建 String
let s = String::from("initial contents");
修改字符串
// 使用 push_str 方法向 String 附加字符串 slice
let mut s = String::from("foo");
s.push_str("bar");
// 使用 push 将一个字符加入 String 值中
let mut s = String::from("lo");
s.push('l');
// 使用 + 运算符将两个 String 值合并到一个新的 String 值中
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // 注意 s1 被移动了,不能继续使用
// 使用 format! 宏拼接字符串
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);
字符串遍历
// 基于 Unicode 标量值,遍历字符
for c in "नमस्ते".chars() {
println!("{}", c);
}
// 遍历所有字节
for b in "नमस्ते".bytes() {
println!("{}", b);
}
从字符串中获取字形簇是很复杂的,所以标准库并没有提供这个功能。crates.io 上有些提供这样功能的 crate。
哈希 Map
HashMap<K, V>
同样支持泛型。
新建
use std::collections::HashMap;
// 新建一个哈希 map 并插入一些键值对
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
// 用队伍列表和分数列表创建哈希 map
let teams = vec![String::from("Blue"), String::from("Yellow")];
let initial_scores = vec![10, 50];
let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();
访问
// 访问哈希 map 中储存的蓝队分数
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
let team_name = String::from("Blue");
let score = scores.get(&team_name);
println!("Blue: {}", score.unwrap());
// for 循环遍历哈希map中的键值对
for (key, value) in &scores {
println!("{}: {}", key, value);
}
更新
let mut scores = HashMap::new();
// 覆盖特定键对应的值
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);
println!("{:?}", scores);
// 使用 entry 方法只在键没有对应一个值时插入
scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);
println!("{:?}", scores);
// 通过哈希 map 储存单词和计数来统计出现次数
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}", map);
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于