Rust 数据类型

本贴最后更新于 1423 天前,其中的信息可能已经斗转星移

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)。

元组

元组的特点:

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

示例:

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);

相关资料

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

  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖 • 4 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...