数据类型
大约 5 分钟
标量类型
一个标量类型代表一个单个值
整数类型
没有小数部分的数
- 无符号类型以
u
开头,比如u32
- 有符号类型以
i
开头,比如i32
- 有符号
Signed
,范围为到 - 无符号
UnSigned
,范围为到
整数类型列表:
长度 | 有符号 | 无符号 |
---|---|---|
8 位 | i8 | u8 |
16 位 | i16 | u16 |
32 位 | i32 | u32 |
64 位 | i64 | u64 |
128 位 | i128 | u128 |
arch | isize | usize |
usize 和 isize 类型
由计算机的架构决定,32 位系统中usize
相当于u32
整数字面值
进制 | 开头 | 举例 |
---|---|---|
十 | null | 12_345 |
十六 | 0x | 0xff |
八 | 0o | 0o77 |
二 | 0b | 0b10 |
Byte | b'' | b'A' |
整数溢出
- 列如,
u8
的范围为 0-255,如果let a = 256
,则- 在调试模式(debug)下编译,rust 会检测整数溢出,如有出现整数溢出则运行时
panic
- 在发布模式(--release)下编译,rust 不会检测可能的
panic
- 如果发生溢出则进行循环操作, 256->0, 257->1
- 在调试模式(debug)下编译,rust 会检测整数溢出,如有出现整数溢出则运行时
浮点类型
含有小数部分的数
f32
:32 位,单精度f64
:64 位,双精度(默认)
布尔类型
true
flase
字符类型
char
类型.占用 4 字节大小,字面值用单引号- Unicode 标量值,范围:
- U+0000 到 U+D7FF
- U+E000 到 U+10FFFF
复合类型
- 元组(Tuple)
- 可以将多个类型的多个值放在一个类型里
- 长度固定, 声明之后无法修改
let tup: (i32, f64, u8) = (500, 5.5, 255); //访问tuple中的值,`.0`代表元组中的第一个元素的索引 print!("NO.1: {}, NO2.: {}, NO.3:{}",tup.0, tup.1, tup.2);
- 获取 tuple 的元素值
//模式匹配 let tup: (i32, f64, u8) = (500, 5.5, 255); let (a, b ,c);
- 数组
- 每个元素的类型必须相同
- 长度固定, 声明之后无法修改
- EG:
let months = [ "一月", "二月", ];
- 数组类型表示
//第一种,'[a, b]'内指定,a为类型,b为长度 let a:[i32, 5] = [1, 2, 3, 4, 5]; //第二种,'[a, b]'中,a为初始值,b为长度 let a = [3; 5]; //这个相当于 let a = [3, 3, 3, 3, 3];
- 访问数组元素: 使用索引访问
let a = ["one", "two", "three", "four"]; print!("first of a is {}", a[0]);
- 如果在不得已的情况下索引超出了数组的最大元素时,rust 不允许其访问其他内存,所以程序将报错
//假设编译通过 //但是程序运行会报错panic let a: [&str; 4] = ["one", "two", "three", "four"]; let index = [4, 5, 6, 7]; print!("first of a is {}", a[index[1]]);
String 类型
- 比那些基础标量更复杂
- 存储在堆(heap)上
- 标准库提供
let s = String::from("hello");
- 深拷贝内容
let s = String::from("hello");
let s1 = s.clone()
枚举类型
- 自定义的类型
enum IpAddrKind {
v4,
v6
}
fn main() {
//创建枚举值
let four = IpAddrKind::v4;
let six = IpAddrKind::v6;
}
常用集合
Vector
Vec<T>
叫做 Vector- 由标准库提供,可以储存多个值
- 只能存储相同类型的值
- 值在内存中连续存放
/*创建*/ //方法1 let mut a: Vec<i32> = Vec::new(); a.push(1); a.push(2); //方法2 let mut a: Vec<i32> = vec![1, 2, 3, 4, 5]; //读取Vector里面的元素 println!("{}", a[0]); //1.索引 println!("{:#?}", a.get(0)); //2.get()方法,返回Option<>类型的值(Some/None)
HashMap
- 用来储存键值对
- 将数据存在堆内存上
use std::collections::HashMap; fn main() { //方法一 let mut dict = HashMap::new();//HashMap需要知道键值对的类型 dict.insert(String::from("Color"), 10); //方法二 let mut dict: HashMap<String, u32> = HashMap::new(); }
另一种创建 HashMap 的方法:collect 方法
- 在元素类型为 Tuple 的 Vector 上使用 collect 方法,可以组建一个 HashMap:
- 要求 Tuple 有两个值,一个作为 Key,一个作为 Vuale
- collect 方法可以把数据整合成许多集合类型,包括 HashMap,返回值需要显式指明类型
let teams = vec![String::from("bule"), String::from("Color")]; let intial_dict = vec![5, 10]; let dict: HashMap<_, _> = teams.iter().zip(intial_dict.iter()).collect();
- 在元素类型为 Tuple 的 Vector 上使用 collect 方法,可以组建一个 HashMap:
访问 HashMap 中的值
- get 方法:参数
K
,返回Option<&V>
- get 方法:参数
HashMap 的大小可变
每个 K 只能对应一个 V
更新 HashMap 中的数据
K 已经存在,对应一个 V
- 替换现有的 V
let mut scores = HashMap::new(); scores.insert(String::from("blue"), 5); scores.insert(String::from("blue"), 10); //println!("{:#?}", scores) //blue对应值为10
- 保留现有的 V
let mut scores = HashMap::new(); scores.insert(String::from("blue"), 5); scores.entry(String::from("red")).or_insert(25); //entry方法检测key是否已存在对应的value,不存在则执行方法or_insert //or_insert方法将default参数作为key的新值 scores.entry(String::from("blue")).or_insert(10);
理解:
fn main() { let text = "hello rust world"; //println!("{:#?}", text.split_whitespace()); let mut map = std::collections::HashMap::new(); for word in text.split_whitespace() { let count = map.entry(word).or_insert(0); //println!("{:#?}", word); *count += 1; } println!("{:#?}", map) }
合并现有的 V 和新的 V
K 不存在
- 添加一对 K,V
结构体 struct
- 定义结构体
- 结构体可以定义在任何地方
struct User {
active: bool,
username: String,
email: String,
uid: u32,
}
- 创建结构体实例
let mut user_one = User {
active: true,
username: String::from("name"),
email: String::from("ecample@domain.com"),
uid: 1,
};
//如果结构体可变,更改结构体中的键值对
user_one.email = String::from("example@domain.com");
- 字段初始化简写语法
fn build_user(username: String, email: String) -> User {
User {
username,
email,
active: true,
uid: 1,
}
}
传入的username
参数与 User 结构体中的username
名称相同,这样就无需再写email: email
- 使用结构体更新语法从其他的实例创建实例
fn main() {
let user = User {
username: String::from("name"),
email: String::from("example@domain.com"),
active: true,
uid: 1,
};
//--snip--
let usert = User {
active: user.active,
email: user.email,
uid: 2,
username: String::from("named"),
};
}