rust基础(一)

大家好,我是鱼樱!!!

关注公众号【鱼樱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(值为 truefalse
基本类型 字符类型 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:结合模式匹配使用,适用于处理 OptionResult 类型的迭代。

在 Rust 中,0..10 是一个 范围(Range) 表达式,表示一个左闭右开的区间,即从 010 的整数序列,不包含 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);
}

这段代码会打印从 09 的所有整数。

对比其他范围表达式:

表达式 含义 包含的值示例
0..10 左闭右开区间 0, 1, 2, ..., 9
0..=10 闭区间(包含两端) 0, 1, 2, ..., 10
..10 从开始到结束(常用于切片) 从 0 到 9
5.. 从起始值到无穷大(常用于迭代器) 5, 6, 7, ...

..小结:

  • 0..10 表示一个从 010 的范围,不包含 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. 使用 mapfilter 等函数式操作

rust 复制代码
let squares: Vec<_> = (1..6).map(|x| x * x).collect();
let evens: Vec<_> = (1..11).filter(|x| x % 2 == 0).collect();

注意事项

注意点 说明
迭代器是惰性的 mapfilter 等不会立即执行,需要调用 collectfor 循环才会触发执行
避免多次使用同一个迭代器 一旦迭代器被消费(如调用 forcollect),就不能再次使用
选择合适的迭代方式 根据是否需要所有权选择 iterinto_iteriter_mut
性能优化 Rust 的迭代器在编译时会优化为高效的底层代码,接近甚至优于手动循环
不可变 vs 可变迭代器 如果需要修改元素,使用 iter_mut() 并注意借用规则

迭代器总结

  • Rust 的迭代器是功能强大且类型安全的工具,适用于各种集合的遍历和处理。
  • 掌握 .iter().into_iter().iter_mut() 的区别是使用迭代器的关键。
  • 迭代器配合 mapfilterfold 等方法可以写出简洁、函数式的代码。
  • 注意迭代器的惰性求值特性,避免误用导致逻辑错误或性能问题。
相关推荐
倪旻萱16 分钟前
XSS漏洞----基于Dom的xss
前端·xss
JSON_L2 小时前
Vue rem回顾
前端·javascript·vue.js
brzhang4 小时前
颠覆你对代码的认知:当程序和数据只剩下一棵树,能读懂这篇文章的人估计全球也不到 100 个人
前端·后端·架构
斟的是酒中桃5 小时前
基于Transformer的智能对话系统:FastAPI后端与Streamlit前端实现
前端·transformer·fastapi
烛阴5 小时前
Fract - Grid
前端·webgl
JiaLin_Denny5 小时前
React 实现人员列表多选、全选与取消全选功能
前端·react.js·人员列表选择·人员选择·人员多选全选·通讯录人员选择
brzhang5 小时前
我见过了太多做智能音箱做成智障音箱的例子了,今天我就来说说如何做意图识别
前端·后端·架构
为什么名字不能重复呢?6 小时前
Day1||Vue指令学习
前端·vue.js·学习
eternalless6 小时前
【原创】中后台前端架构思路 - 组件库(1)
前端·react.js·架构
Moment6 小时前
基于 Tiptap + Yjs + Hocuspocus 的富文本协同项目,期待你的参与 😍😍😍
前端·javascript·react.js