大家好,我是鱼樱!!!
关注公众号【鱼樱AI实验室】
持续分享更多前端和AI辅助前端编码新知识~~
不定时写点笔记写点生活~写点前端经验。
在当前环境下,纯前端开发者可以通过技术深化、横向扩展、切入新兴领域以及产品化思维找到突破口。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
前端最卷的开发语言一点不为过,三天一小更,五天一大更。。。一年一个框架升级~=嗯,要的就是这样感觉!与时俱进~
注释
rust
// 这是第一种注释方式
/* 这是第二种注释方式 */
/*
* 多行注释
* 多行注释
* 多行注释
*/
变量
Rust 是强类型语言,但具有自动判断变量类型的能
默认情况下,Rust 中的变量是不可变的,除非使用 mut
关键字声明为可变变量
声明变量,需要使用 let
关键字
变量的值可以"重新绑定",但在"重新绑定"以前不能私自被改变,这样可以确保在每一次"绑定"之后的区域里编译器可以充分的推理程序逻辑
rust
// 变量声明
let x = 5;
// 打印语句
println!("x: {}", x); // x: 5
// 错误的三种
// x = "123";
// x = 1.23;
// x = 3;
// 可变变量
let mut y = 10;
y += 5;
// 打印语句
println!("y: {}", y); // y: 15
// 变量和常量还是有区别的
let a = 123; // 可以编译,但可能有警告,因为该变量没有被使用
let a = 456;
数据类型
Rust 的数据类型可以分为基本类型(Primitive Types)和复合类型(Compound Types)两大类
Rust 是静态类型语言,在变量声明时可以显式指定类型,但通常可以依赖类型推断。
- 基本类型: i32 (32位有符号整数), u32 (32位无符号整数), f64 (64位浮点数), bool (布尔类型), char (字符)
- 复合类型: 元组(Tuple)、数组(Array)、切片(Slice)、结构体(Struct)、枚举(Enum)
数据类型分类
类型类别 | 类型名称 | 描述 |
---|---|---|
基本类型 | 整数类型 | i8 , i16 , i32 , i64 , i128 (有符号) u8 , u16 , u32 , u64 , u128 (无符号) isize , usize (根据平台决定大小) |
基本类型 | 浮点类型 | f32 , f64 |
基本类型 | 布尔类型 | bool (值为 true 或 false ) |
基本类型 | 字符类型 | char (表示 Unicode 字符) |
复合类型 | 元组(Tuple) | 一组不同类型的值组合,如 (i32, f64, char) |
复合类型 | 数组(Array) | 固定长度的相同类型元素集合,如 [i32; 5] |
复合类型 | 切片(Slice) | 对数组或字符串的引用,如 &[i32] 或 &str |
复合类型 | 结构体(Struct) | 自定义类型的复合数据结构 |
复合类型 | 枚举(Enum) | 多个可能值的类型,如 Option<T> 和 Result<T, E> |
对比表
特性 | 基本类型 | 复合类型 |
---|---|---|
组成 | 单一值 | 多个值或不同类型组合 |
示例 | i32 , f64 , bool , char |
tuple , array , slice , struct , enum |
用途 | 表示简单的数据值 | 表示复杂的数据结构 |
可变性 | 可变或不可变变量 | 通常需要通过 mut 关键字声明可变性 |
内存管理 | 通常存储在栈上 | 可能引用堆内存(如 Vec<T> , String ) |
数据类型示例:
rust
// 基本类型
let integer: i32 = 10;
let float: f64 = 3.14;
let boolean: bool = true;
let character: char = 'A';
// 元组
let tuple: (i32, f64, char) = (10, 3.14, 'A');
// 数组
let array: [i32; 3] = [1, 2, 3];
// 切片
let slice: &[i32] = &array[..];
// 结构体
struct Point {
x: i32,
y: i32,
}
// 枚举
enum Option<T> {
Some(T),
None,
}
函数
rust
fn <函数名> ( <参数> ) <函数体>
Rust 函数通过 fn
关键字定义,函数的返回类型通过箭头符号 ->
指定
Rust 不支持自动返回值类型判断!如果没有明确声明函数返回值的类型,函数将被认为是"纯过程",不允许产生返回值,return 后面不能有返回值表达式。
注意: 函数体表达式并不能等同于函数体,它不能使用 return 关键字。
Rust 中定义函数如果需要具备参数必须声明参数名称和类型
rust
// 如果函数没有返回值,类型默认为 ()(即空元组)
fn add(a: i32, b: i32) -> i32 {
a + b
}
条件语句
Rust 中的 if
不存在单语句不用加 {}
的规则,不允许使用一个语句代替一个块。尽管如此,Rust 还是支持传统 else-if
语法的
Rust 中的条件表达式必须是 bool 类型
注意:两个函数体表达式的类型必须一样!且必须有一个 else 及其后的表达式块
rust
fn main() {
let number = 1;
if number < 3 {
println!("条件为 true");
} else {
println!("条件为 false");
}
}
循环
Rust 中的循环种类
循环类型 | 语法 | 描述 |
---|---|---|
loop |
loop { ... } |
无限循环,直到遇到 break 为止 |
while |
while condition { ... } |
条件为 true 时循环执行代码块 |
for |
for item in iterator { ... } |
遍历一个迭代器(如数组、范围等) |
while let |
while let Some(value) = iterator.next() { ... } |
当模式匹配时持续循环(常用于迭代器) |
for 循环结合 Range |
for i in 0..5 { ... } |
遍历一个范围(如 0..5 表示 0 到 4) |
示例代码
1. loop
场景:某个个循环无法在开头和结尾判断是否继续进行循环,必须在循环体中间某处控制循环的进行。如果遇到这种情况,我们经常会在一个 while (true) 循环体里实现中途退出循环的操作
loop 循环可以通过 break 关键字类似于 return 一样使整个循环退出并给予外部一个返回值。
rust
let mut counter = 0;
loop {
println!("Counter: {}", counter);
counter += 1;
if counter == 3 {
break;
}
}
2. while
rust
let mut number = 1;
while number != 4 {
println!("{}", number);
number += 1;
}
println!("EXIT");
3. for
遍历数组
rust
let arr = [10, 20, 30, 40, 50];
for element in arr.iter() {
println!("Element: {}", element);
}
4. for
遍历范围
rust
for i in 0..5 {
println!("i = {}", i);
}
5. while let
(用于模式匹配)
rust
let mut stack = vec![1, 2, 3];
while let Some(top) = stack.pop() {
println!("Popped: {}", top);
}
循环语句总结
Rust 提供了多种循环结构,适用于不同的场景:
loop
:无限循环,手动控制退出。while
:根据条件循环。for
:遍历迭代器或范围,最常用且安全。while let
:结合模式匹配使用,适用于处理Option
或Result
类型的迭代。
在 Rust 中,0..10
是一个 范围(Range) 表达式,表示一个左闭右开的区间,即从 0
到 10
的整数序列,不包含 10。
含义:
0..10
表示的值是:0, 1, 2, 3, 4, 5, 6, 7, 8, 9
类型:
0..10
的类型是 std::ops::Range<i32>
,即 Range
结构体,定义为:
rust
struct Range {
start: i32,
end: i32,
}
常见用法:
通常用于 for
循环中遍历数字序列:
rust
for i in 0..10 {
println!("{}", i);
}
这段代码会打印从 0
到 9
的所有整数。
对比其他范围表达式:
表达式 | 含义 | 包含的值示例 |
---|---|---|
0..10 |
左闭右开区间 | 0, 1, 2, ..., 9 |
0..=10 |
闭区间(包含两端) | 0, 1, 2, ..., 10 |
..10 |
从开始到结束(常用于切片) | 从 0 到 9 |
5.. |
从起始值到无穷大(常用于迭代器) | 5, 6, 7, ... |
..小结:
0..10
表示一个从0
到10
的范围,不包含 10- 常用于
for
循环中遍历数字序列 - 是 Rust 中非常常见且高效的迭代方式之一
迭代器(Iterator)
Rust 中的迭代器(Iterator)是一种用于遍历集合(如数组、向量、字符串等)的抽象机制,具有高效、安全、灵活的特点。
Rust 中,迭代器通过实现 Iterator trait 来定义
.iter()
:返回集合的不可变引用迭代器。.iter_mut()
:返回集合的可变引用迭代器。.into_iter()
:将集合转移所有权并生成值迭代器。
迭代器遵循以下原则:
- 惰性求值 (Laziness) :Rust 中的迭代器是惰性的,意味着迭代器本身不会立即进行任何计算或操作,直到你显式地请求数据。这使得迭代器在性能上表现良好,可以避免不必要的计算。
- 所有权和借用检查 (Ownership and Borrowing Checks) :Rust 迭代器严格遵守所有权和借用规则,避免数据竞争和内存错误。迭代器的生命周期与底层数据相关联,确保数据的安全访问。
- 链式调用 (Chaining) :Rust 迭代器支持链式调用,即可以将多个迭代器方法链接在一起进行组合操作,这使得代码简洁且具有高度可读性。例如,通过使用
.map()
、.filter()
、.collect()
等方法,可以创建复杂的数据处理流水线。 - 高效内存管理 (Efficient Memory Management) :迭代器避免了不必要的内存分配,因为大多数操作都是惰性求值的,并且在使用时直接进行遍历操作。这对于处理大数据集合尤其重要。
- 抽象和通用性 (Abstraction and Generality) :Rust 的迭代器通过
Iterator
trait 实现抽象和通用性。任何实现了Iterator
trait 的类型都可以在不同的上下文中作为迭代器使用。此设计提高了代码的重用性和模块化。
一、迭代器概念
在 Rust 中,迭代器是惰性求值的(lazy),即只有在真正使用时才会执行。迭代器主要通过 .iter()
、.into_iter()
、.iter_mut()
等方法创建。
方法 | 用途 | 所有权 |
---|---|---|
.iter() |
不可变借用集合中的每个元素 | 不获取所有权 |
.into_iter() |
获取集合所有权,并遍历元素 | 获取所有权 |
.iter_mut() |
可变借用集合中的每个元素 | 不获取所有权 |
常用用法
1. 遍历数组
rust
let a = [10, 20, 30, 40, 50];
for i in a.iter() {
println!("值为 : {}", i);
}
2. 遍历向量
rust
let v = vec![1, 2, 3];
for num in v.iter() {
println!("{}", num);
}
// 1
// 2
// 3
3. 遍历范围
rust
for i in 0..5 {
println!("{}", i);
}
4. 使用 enumerate
获取索引和值
rust
for (index, &value) in a.iter().enumerate() {
println!("索引: {}, 值: {}", index, value);
}
5. 使用 map
、filter
等函数式操作
rust
let squares: Vec<_> = (1..6).map(|x| x * x).collect();
let evens: Vec<_> = (1..11).filter(|x| x % 2 == 0).collect();
注意事项
注意点 | 说明 |
---|---|
迭代器是惰性的 | 如 map 、filter 等不会立即执行,需要调用 collect 或 for 循环才会触发执行 |
避免多次使用同一个迭代器 | 一旦迭代器被消费(如调用 for 或 collect ),就不能再次使用 |
选择合适的迭代方式 | 根据是否需要所有权选择 iter 、into_iter 、iter_mut |
性能优化 | Rust 的迭代器在编译时会优化为高效的底层代码,接近甚至优于手动循环 |
不可变 vs 可变迭代器 | 如果需要修改元素,使用 iter_mut() 并注意借用规则 |
迭代器总结
- Rust 的迭代器是功能强大且类型安全的工具,适用于各种集合的遍历和处理。
- 掌握
.iter()
、.into_iter()
和.iter_mut()
的区别是使用迭代器的关键。 - 迭代器配合
map
、filter
、fold
等方法可以写出简洁、函数式的代码。 - 注意迭代器的惰性求值特性,避免误用导致逻辑错误或性能问题。