Rust进阶[part3]_生命周期
生命周期概述
在Rust中,生命周期是一种确保引用有效性的机制。Rust编译器通过生命周期注解来跟踪引用的作用域,防止出现悬空引用(dangling references)。
简单使用
下面是一个简单的生命周期注解示例:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(&string1, string2);
println!("The longest string is {}", result);
}
在这个例子 ...
Rust进阶[part2]_泛型
泛型概述
在定义函数时运用泛型,可将原本函数签名里明确指定参数和返回值类型的部分,用泛型来替代。这种方式能增强代码的适应性,为函数调用者赋予更多功能,还能避免代码重复。
fn add<T>(a:T, b:T) -> T{
a + b
}
不过,并非所有的T类型都能进行相加操作,此时会提示错误:
genertic_type.rs(5, 9): consider restricting type parameter 'T' with trait 'Add': ': std::ops::Add<Output = T>'
修正后的代码如下:
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
使用场景
在函数定义中使用泛型
fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> &T {
let mut largest ...
Rust进阶[part1]_智能指针概述&box指针
智能指针概述
在Rust中,智能指针是一类特殊的数据结构,它们不仅像普通指针一样可以引用数据,还带有额外的元数据和功能。与普通指针不同,智能指针通常使用结构体实现,并且会实现 Deref 和 Drop 等特定的trait,以提供更强大的功能和更安全的内存管理。
智能指针在Rust编程中扮演着重要的角色,它们能够帮助开发者处理复杂的内存管理场景,确保程序的安全性和性能。例如,在处理动态大小的数据、递归数据结构或者需要自定义资源释放逻辑时,智能指针就显得尤为重要。
Box指针
内存分配到堆上
在Rust中,栈内存的分配和释放是自动且高效的,但栈空间是有限的。对于一些大型的数据结构或者需要在运行时动态确定大小的数据,将其存储在栈上可能会导致栈溢出。这时,我们可以使用 Box 指针将数据分配到堆上。
Box 是Rust标准库中最基本的智能指针之一,它允许我们在堆上分配内存,并将数据存储在其中。通过 Box 指针,我们可以在栈上存储一个指向堆上数据的引用,从而实现对堆上数据的访问。
以下是一个简单的示例,展示了如何使用 Box 将一个 ...
Rust基础[part9]_返回值和错误处理、模块化
返回值
Option<T>
基本使用
fn option_example() {
// 创建Option
let some_number = Some(5);
let some_string = Some("a string");
let absent_number: Option<i32> = None;
//使用
let x = plus_one(some_number);
let y = plus_one(absent_number);
println!("x: {:?}, y: {:?}", x, y);
}
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
} ...
Rust基础[part8]_模式匹配、常见集合
模式匹配
检查数据结构,提高代码的可读性和简洁性,减少错误,尤其在处理复杂数据结构的时候
基础模式匹配
fn match_example() {
let x = 5;
// 必须要有所有可能的case
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("something else"),
}
}
守卫
在模式匹配中,可以总使用守卫来添加额外的条件判断。
let x = 5;
match x {
n if n > 5 => println!("x is greater than 5"),
_ => println!("x is less than or equal to 5"),
}
绑定
在模式匹配中,可以使用绑定来将模式中的值绑定到变量 ...
Rust基础[part7]_枚举、结构体
枚举
枚举用于表示一个值可能是多种变体(Variant)中的一种。每个变体可以有不同的数据类型:
enum Message {
Quit, // 无数据
Move { x: i32, y: i32 }, // 带命名数据(类似结构体)
Write(String), // 带单个值(类似元组)
ChangeColor(i32, i32, i32), // 带多个值(类似元组)
}
基本使用
enum Pets {
Cat(String),
Dog { name: String, age: usize },
}
fn print_pet_info() {
let a = Pets::Cat("Whiskers".to_string());
let b = Pets::Dog {
name: "Buddy".to_st ...
Rust基础[part6]_数组与切片、字符串
数组
数组的类型格式:[T; N]
固定长度:必须在编译时指定长度 N,且无法扩容。
可变:如果声明为 mut,可以修改元素值,但不能改变长度。
存储在栈上(除非被装箱到堆上,如 Box<[T; N]>)。
定义
let arr = [1, 2, 3, 4, 5];
println!("Array: {:?}", arr);
默认初始值
// 默认初始值
let arr1: [i32; 4] = [10; 4];
println!("Array with default value: {:?}", arr1);
数组长度
// 数组长度
println!("Array length: {}", arr1.len());
遍历
for index in 0..arr.len() {
// 遍历索引
println!("Element at index {}: {} ...
Rust基础[part5]_引用
不可变引用:通过不可变引用,可以读取变量,但是不能够修改数据。一个变量可以有多个不可变引用,但不能与可变引用共存。
可变引用:通过可变引用,可以读取和修改数据。一个变量在某一时刻只能有一个可变引用,且不能与不可变引用共存。
引用规则
同一时间(生命周期)内,一个变量只能有一个可变引用或多个不可变引用
多个不可变引用可以共存
可变引用必须是独占的(不能与其他引用共存)
引用必须总是有效(Rust保证引用永远不会指向无效内存)
示例1:错误示范
pub fn reference_example() {
let mut s: String = String::from("Hello");
// 创建不可变引用
let s1: &String = &s;
// 创建可变引用(错误:此时s已有不可变引用)
let s2: &mut String = &mut s;
// 错误:不能创建多个可变引用
let s3: &mut String ...
Rust基础[part4]_基本类型,所有权
Rust类型
概览
以下是整合后的 Rust 类型说明表格:
类型
说明
值
i8、i16、i32、i64、i128、u8、u16、u32、u64、u128
给定位宽的有符号整数和无符号整数
42、-5i8、0x400u16、0o100i16、20_922_789_888_000u64、b'*'(u8 字节字面量)
isize、usize
与机器字(32 位或 64 位)一样大的有符号整数和无符号整数
137、-0b0101_0010isize、0xffff_fc00usize
f32、f64
单精度 IEEE 浮点数和双精度 IEEE 浮点数
1.61803、3.14f32、6.0221e23f64
bool
布尔值
true、false
char
Unicode 字符,32 位宽(4 字节)
'*'、'\n'、'字'、'\x7f'、'\u{...}'(Unicode 转义)
(char, u8, i32)
元组,允许混合类型
('%', 0x7f, -1)
()
“单元”(空元组 ...
Rust基础[part3]_函数、流程控制
函数
组成和定义
fn add(i: i32, j: i32) -> i32 {
i + j
}
声明函数的关键字 fn
函数名add()
参数i和j和参数类型 i32
返回值类型`i32``
函数题i+j
函数返回
返回形态
i+j 和 return i+j;
可以有两种形态
return + 分号
无return + 无分号
无返回值的情况:
就返回 ()
fn add(i: i32, j: i32) -> () {
}
永不返回值的情况:
!表示函数永不返回,例如panic!宏会导致程序崩溃,函数不会返回。
fn add_one(i: i32, j: i32) -> ! {
panic!("weeee");
}
死循环也不会返回
fn infinite_loop() -> ! {
loop {
// 永远不会返回
}
}
流程控制
if语法
// if_else();
...