【Rust编程:从新手到大师】Rust变量深度详解

本文聚焦 Rust 变量的核心特性,从 "定义 - 可变性 - 遮蔽 - 作用域 - 生命周期" 全流程展开,通过对比案例、错误分析、实操技巧,帮零基础学生理解 Rust 变量与其他语言的差异,掌握规范使用方法,为后续学习打下坚实基础。

一、Rust 变量的核心本质

在 Rust 中,变量不仅是 "存储数据的容器",更是 "内存安全的守护者"。Rust 通过变量的不可变性默认显式可变性作用域约束等设计,从源头避免内存泄漏、数据竞争等问题,这是 Rust 与 C/C++、Python 等语言的核心区别。

1.1 变量与内存的关系

每一个变量在定义时,Rust 都会:

  1. 为变量在内存中分配一块 "固定大小" 的空间(大小由变量类型决定,如i32占 4 字节、bool占 1 字节);

  2. 将数据存入该内存空间;

  3. 记录变量的 "作用域"(变量生效的代码范围),作用域结束后自动释放内存(无需手动管理,避免内存泄漏)。

案例 1:变量的内存分配示意
复制代码
fn main() {

   // 定义i32类型变量x,内存分配4字节,存入值5

   let x: i32 = 5;

   println!("x的值:{}", x);

   // 此处x的作用域结束,内存自动释放

}

二、变量的定义与初始化

Rust 对变量的 "定义" 和 "初始化" 有严格要求,核心原则:变量必须初始化后才能使用(避免使用未初始化的脏数据,保障内存安全)。

2.1 基本定义语法

变量定义的基础语法:let [mut] 变量名[: 类型] = 初始值;,其中[]内为可选内容。

2.1.1 类型推断(推荐)

Rust 能根据 "初始值" 自动推断变量类型,无需手动指定,减少冗余代码:

复制代码
fn main() {

   // 类型推断为i32(整数默认类型)

   let age = 25;

   // 类型推断为f64(浮点数默认类型)

   let height = 1.75;

   // 类型推断为bool

   let is\_student = true;

   // 类型推断为char

   let initial = 'A';

   // 类型推断为\&str(字符串切片,后续详解)

   let name = "张三";

  

   println!("年龄:{}(类型:i32)", age);

   println!("身高:{}(类型:f64)", height);

}
2.1.2 显式指定类型(必要场景)

当 "初始值无法明确类型" 或 "需要指定非默认类型" 时,必须显式标注类型:

复制代码
fn main() {

   // 场景1:初始值为0,需指定为u8类型(默认是i32)

   let byte: u8 = 0;

   // 场景2:空字符串切片,需指定类型(无法推断)

   let empty\_str: \&str = "";

   // 场景3:科学计数法,需指定为f32(默认是f64)

   let small\_float: f32 = 1e-3;

  

   println!("字节值:{}(类型:u8)", byte);

   println!("空字符串:{}(类型:\&str)", empty\_str);

}
2.1.3 错误案例:未初始化变量

Rust 不允许定义 "未初始化的变量",编译时会直接报错:

复制代码
fn main() {

   // 错误:变量x未初始化

   let x: i32;

   // println!("x的值:{}", x);  // 取消注释后编译报错:use of possibly uninitialized variable \`x\`

   x = 10;  // 必须先赋值,再使用

   println!("x的值:{}", x);  // 正确:赋值后可使用

}

2.2 变量的可变性:默认不可变(Immutable)

Rust 变量默认 "不可变"------ 即变量赋值后,值不能修改。这是 Rust 保障 "数据一致性" 和 "线程安全" 的核心设计,避免意外修改导致的 bug。

2.2.1 不可变变量的特性
复制代码
fn main() {

   // 定义不可变变量(默认)

   let price = 99;

   println!("初始价格:{}", price);

  

   // 尝试修改不可变变量(错误)

   // price = 89;  // 编译报错:cannot assign twice to immutable variable \`price\`

}
2.2.2 显式可变:mut 关键字

若需要动态修改变量的值,需在定义时添加mut关键字(mut = mutable,可变的):

复制代码
fn main() {

   // 用mut定义可变变量

   let mut count = 0;

   println!("初始计数:{}", count);

  

   // 第一次修改

   count = count + 1;

   println!("修改后计数1:{}", count);  // 输出1

  

   // 第二次修改

   count \*= 2;

   println!("修改后计数2:{}", count);  // 输出2

}
2.2.3 可变变量的限制

即使使用mut,变量的 "类型" 也不能改变 ------Rust 是静态类型语言,类型一旦确定,终身不变:

复制代码
fn main() {

   let mut num = 10;  // 类型为i32

   num = 20;          // 正确:类型不变,仅值修改

   // num = "20";      // 错误:类型不匹配(i32 vs \&str)

}

三、变量遮蔽(Shadowing):重新定义同名变量

Rust 允许在同一作用域内,用let重新定义 "同名变量",新变量会 "遮蔽" 旧变量(旧变量在当前作用域内失效)。这与 "可变变量" 有本质区别,是 Rust 特有的变量特性。

3.1 变量遮蔽的基础用法

复制代码
fn main() {

   // 第一次定义变量x(i32类型,值5)

   let x = 5;

   println!("第一次定义x:{}(类型:i32)", x);  // 输出5

  

   // 第二次定义x(遮蔽旧x,值x+3=8,类型仍为i32)

   let x = x + 3;

   println!("第二次定义x:{}(类型:i32)", x);  // 输出8

  

   // 第三次定义x(遮蔽旧x,值"x is 8",类型变为\&str)

   let x = format!("x is {}", x);

   println!("第三次定义x:{}(类型:\&str)", x);  // 输出"x is 8"

}

3.2 变量遮蔽 vs 可变变量(核心区别)

很多零基础学生容易混淆 "变量遮蔽" 和 "可变变量",两者的核心差异如下:

对比维度 变量遮蔽(let 重定义) 可变变量(mut)
语法 let x = 5; let x = 10; let mut x = 5; x = 10;
是否创建新变量 是(每次 let 都创建新变量,旧变量失效) 否(仅修改原有变量的值,不创建新变量)
能否改变类型 能(新变量可与旧变量类型不同) 不能(类型必须始终一致)
作用域影响 新变量定义后,旧变量在当前作用域失效 变量始终有效,直到作用域结束
内存分配 每次遮蔽都重新分配内存 仅一次内存分配,后续修改值
案例 2:对比演示
复制代码
fn main() {

   // 案例A:变量遮蔽(可改变类型)

   let a = 10;          // i32类型

   let a = a.to\_string();// 遮蔽旧a,类型变为String

   println!("变量遮蔽a:{}(类型:String)", a);

  

   // 案例B:可变变量(不可改变类型)

   let mut b = 10;      // i32类型

   b = 20;              // 正确:类型不变

   // b = b.to\_string();  // 错误:类型不匹配(i32 vs String)

   println!("可变变量b:{}(类型:i32)", b);

}

3.3 变量遮蔽的适用场景

  1. 类型转换:需要将变量从一种类型转为另一种类型,且希望保留变量名(如整数转字符串);

  2. 值预处理:对变量值进行加工后,用同名变量存储结果(如去空格、格式化);

  3. 缩小变量范围:在子作用域内重新定义变量,避免影响外部作用域。

案例 3:变量遮蔽的实际应用
复制代码
fn main() {

   // 原始输入(带空格的字符串)

   let input = "  123  ";

   println!("原始输入:{}", input);

  

   // 第一步:去除空格(遮蔽旧input,类型仍为\&str)

   let input = input.trim();

   println!("去空格后:{}", input);

  

   // 第二步:转为整数(遮蔽旧input,类型变为i32)

   let input: i32 = input.parse().unwrap();

   println!("转为整数后:{}(类型:i32)", input);

  

   // 第三步:计算平方(遮蔽旧input,类型仍为i32)

   let input = input \* input;

   println!("平方结果:{}", input);

}
运行结果:
复制代码
原始输入:   123 

去空格后:123

转为整数后:123(类型:i32)

平方结果:15129

四、变量的作用域(Scope):变量的 "生效范围"

变量的 "作用域" 是指 "变量能被访问的代码范围",超出范围后变量自动失效,内存被释放(Rust 的 "所有权" 机制基础,后续详解)。

4.1 作用域的基本规则

Rust 中,作用域通常由 "花括号{}" 划分,常见场景:

  1. 函数作用域:变量在fn main() {}内定义,仅在函数内生效;

  2. 代码块作用域:变量在if {}for {}{}等代码块内定义,仅在块内生效;

  3. 子作用域:在父作用域内嵌套子作用域,子作用域可访问父作用域变量,但父作用域不能访问子作用域变量。

案例 4:不同作用域的变量访问
复制代码
fn main() {

   // 父作用域变量:在main函数内生效

   let parent\_var = "父作用域变量";

   println!("父作用域内访问:{}", parent\_var);

  

   // 子作用域(用{}创建)

   {

       // 子作用域变量:仅在当前{}内生效

       let child\_var = "子作用域变量";

       // 子作用域可访问父作用域变量

       println!("子作用域内访问父变量:{}", parent\_var);

       println!("子作用域内访问子变量:{}", child\_var);

   }

   // 父作用域不能访问子作用域变量(错误)

   // println!("父作用域访问子变量:{}", child\_var);  // 编译报错:cannot find value \`child\_var\` in this scope

}
运行结果:
复制代码
父作用域内访问:父作用域变量

子作用域内访问父变量:父作用域变量

子作用域内访问子变量:子作用域变量

4.2 作用域与变量遮蔽的结合

在子作用域内,可通过 "变量遮蔽" 重新定义父作用域的同名变量,且仅在子作用域内生效,不影响父作用域变量:

复制代码
fn main() {

   let x = 10;  // 父作用域变量x

   println!("父作用域x:{}", x);  // 输出10

  

   {

       // 子作用域遮蔽x,仅在子作用域内生效

       let x = 20;

       println!("子作用域x(遮蔽后):{}", x);  // 输出20

   }

  

   // 父作用域x不受子作用域遮蔽影响

   println!("父作用域x(子作用域后):{}", x);  // 输出10

}
运行结果:
复制代码
父作用域x:10

子作用域x(遮蔽后):20

父作用域x(子作用域后):10

五、变量的生命周期(Lifetime):变量的 "存活时间"

变量的 "生命周期" 与 "作用域" 紧密相关,指 "变量从定义到作用域结束的存活时间"。在 Rust 中,生命周期由编译器自动管理,无需手动控制,核心规则:

  1. 变量在定义时 "出生"(分配内存);

  2. 变量在作用域结束时 "死亡"(释放内存);

  3. 生命周期内,变量可被多次访问和修改(若可变)。

5.1 生命周期的实际体现

复制代码
fn main() {

   // 变量a的生命周期开始(分配内存)

   let a = 5;

   println!("a的生命周期内:{}", a);

  

   // 变量b的生命周期开始

   let mut b = 10;

   b = 20;  // 可变变量,生命周期内可修改

   println!("b的生命周期内:{}", b);

   // 变量b的生命周期结束(main函数结束前)

  

   // 变量a的生命周期结束(main函数结束)

}

5.2 生命周期与内存安全

Rust 通过 "生命周期约束",避免 "悬垂引用"(引用了已释放的变量内存),这是 Rust 内存安全的核心保障。后续学习 "引用" 和 "所有权" 时会深入讲解,此处先了解基础概念:

复制代码
fn main() {

   let reference;  // 定义引用变量

   {

       let x = 5;  // x的生命周期开始

       reference = \&x;  // 引用x的内存

       println!("子作用域内引用x:{}", reference);  // 正确:x仍存活

   }  // x的生命周期结束,内存释放

   // 错误:引用了已释放的x的内存(悬垂引用)

   // println!("父作用域引用x:{}", reference);  // 编译报错:borrowed value does not live long enough

}

六、常量(Constant):特殊的 "不可变变量"

Rust 中的 "常量" 与 "不可变变量" 相似(值都不能修改),但有本质区别,是专门用于存储 "编译期已知、全局生效、永不改变的值" 的变量类型。

6.1 常量的定义语法

常量定义的语法:const 常量名: 类型 = 初始值;,注意:

  1. 必须显式指定类型(不能依赖类型推断);

  2. 初始值必须是 "编译期可计算的值"(不能是运行时才能确定的值,如用户输入、随机数);

  3. 常量名通常用 "全大写 + 下划线" 命名(规范);

  4. 常量可在全局作用域定义(函数外),全程序生效。

案例 5:常量的使用
复制代码
// 全局常量:在函数外定义,全程序生效

const MAX\_SCORE: i32 = 100;

const PI: f64 = 3.1415926;

fn main() {

   // 函数内使用全局常量

   println!("满分:{}", MAX\_SCORE);

   println!("圆周率:{}", PI);

  

   // 函数内定义局部常量(较少用,通常全局定义)

   const MIN\_AGE: u8 = 18;

   println!("最小年龄:{}", MIN\_AGE);

  

   // 常量不能修改(错误)

   // MAX\_SCORE = 90;  // 编译报错:cannot assign to \`MAX\_SCORE\`, which is a constant

}
运行结果:
复制代码
满分:100

圆周率:3.1415926

最小年龄:18

6.2 常量 vs 不可变变量(区别)

对比维度 常量(const) 不可变变量(let)
类型推断 不支持,必须显式指定类型 支持,可通过初始值自动推断类型
定义位置 可在全局作用域(函数外)或局部作用域 仅能在局部作用域(函数内、代码块内)
初始值要求 必须是编译期可计算的值(如字面量、编译期常量表达式) 可是编译期值或运行时值(如用户输入、函数返回值)
内存分配 编译期嵌入代码,运行时无额外内存分配 运行时在栈上分配内存,作用域结束释放
命名规范 全大写 + 下划线(如MAX_SCORE),强制规范 蛇形命名(如max_score),建议规范
适用场景 存储全局固定值(如最大值、常量配置) 存储局部固定值(如临时计算结果)
案例 6:常量与不可变变量的场景差异
复制代码
// 全局常量:编译期已知,全程序生效

const MAX\_RETRY: u32 = 3;  // 必须显式指定类型

fn main() {

   // 不可变变量:运行时确定值(如函数返回值)

   let current\_time = get\_current\_second();  // 类型自动推断为u32

   println!("当前秒数:{}", current\_time);

  

   // 常量:编译期已知,用于固定逻辑

   for i in 0..MAX\_RETRY {

       println!("第{}次重试", i + 1);

   }

}

// 模拟获取当前秒数(运行时才能确定值)

fn get\_current\_second() -> u32 {

   // 实际场景中会调用系统API,此处用固定值模拟

   45

}
运行结果:
复制代码
当前秒数:45

第1次重试

第2次重试

第3次重试
关键说明:
  • 常量MAX_RETRY是编译期已知的固定值,适合用于循环次数、配置上限等场景;

  • 不可变变量current_time的值由函数get_current_second()返回(运行时确定),无法用常量定义;

  • 若尝试将运行时值赋值给常量(如const TIME: u32 = get_current_second();),会编译报错,因为常量要求初始值是编译期可计算的。

6.3 静态变量(static):特殊的 "全局变量"

除了常量,Rust 还提供 "静态变量"(static),用于存储 "全局生命周期、运行时初始化" 的变量,与常量的核心区别是:静态变量在运行时分配固定内存(通常在数据段),且可修改(需用static mut)。

静态变量的定义与使用:
复制代码
// 全局静态变量:不可变,全程序生命周期

static GLOBAL\_VERSION: \&str = "1.0.0";

// 可变全局静态变量:需用static mut,访问时需unsafe块(有内存安全风险)

static mut COUNTER: u32 = 0;

fn main() {

   // 访问不可变静态变量(安全,无需unsafe)

   println!("程序版本:{}", GLOBAL\_VERSION);

  

   // 访问可变静态变量(不安全,需用unsafe块)

   unsafe {

       COUNTER += 1;

       println!("计数器:{}", COUNTER);  // 输出1

      

       COUNTER += 1;

       println!("计数器:{}", COUNTER);  // 输出2

   }

}
注意事项:
  • 静态变量的生命周期是 "全局"(程序运行期间始终存在),内存不会自动释放;

  • 不可变静态变量(static)访问安全,可变静态变量(static mut)访问需用unsafe块,因为多线程环境下可能存在数据竞争,风险较高;

  • 零基础阶段建议优先使用常量(const),避免使用static mut,除非有明确的全局变量需求且能保证内存安全。

七、变量相关常见错误与解决方案

零基础学生在使用 Rust 变量时,容易遇到以下几类错误,掌握错误原因和解决方法能大幅提升学习效率。

7.1 错误 1:未初始化变量(use of possibly uninitialized variable)

错误示例:
复制代码
fn main() {

   let x: i32;  // 仅定义,未初始化

   println!("x的值:{}", x);  // 编译报错

}
错误原因:

Rust 不允许使用未初始化的变量,避免访问内存中的 "脏数据"(随机值),保障内存安全。

解决方案:
  1. 定义变量时直接初始化(推荐):let x: i32 = 10;

  2. 若无法立即初始化,确保使用前赋值:

    fn main() {

    复制代码
    let x: i32;
    
    x = 10;  // 使用前赋值
    
    println!("x的值:{}", x);  // 正确

    }

7.2 错误 2:不可变变量重复赋值(cannot assign twice to immutable variable)

错误示例:
复制代码
fn main() {

   let x = 5;

   x = 10;  // 编译报错:不可变变量不能重复赋值

}
错误原因:

变量默认不可变,定义后无法修改值,需显式声明mut才能可变。

解决方案:
  1. 定义变量时添加mut关键字:

    fn main() {

    复制代码
    let mut x = 5;
    
    x = 10;  // 正确:可变变量可重复赋值
    
    println!("x的值:{}", x);  // 输出10

    }

  2. 若无需修改值,删除重复赋值语句;

  3. 若需要改变类型,使用变量遮蔽:let x = 10;(重新定义同名变量)。

7.3 错误 3:变量作用域外访问(cannot find value in this scope)

错误示例:
复制代码
fn main() {

   {

       let x = 5;  // 子作用域变量

   }

   println!("x的值:{}", x);  // 编译报错:子作用域结束,x已失效

}
错误原因:

变量的作用域已结束,变量已失效(内存被释放),无法在作用域外访问。

解决方案:
  1. 将变量定义在更外层的作用域(如父作用域):

    fn main() {

    复制代码
    let x = 5;  // 父作用域变量
    
    {
    
        println!("子作用域内访问x:{}", x);  // 正确:子作用域可访问父作用域变量
    
    }
    
    println!("父作用域内访问x:{}", x);  // 正确

    }

  2. 若变量必须在子作用域内定义,可通过 "返回值" 将变量传递到父作用域:

    fn main() {

    复制代码
    let x = {
    
        let temp = 5;  // 子作用域变量
    
        temp  // 子作用域最后一行的值作为返回值,赋值给x
    
    };
    
    println!("x的值:{}", x);  // 正确:输出5

    }

7.4 错误 4:类型不匹配(mismatched types)

错误示例:
复制代码
fn main() {

   let x: i32 = "5";  // 编译报错:将字符串赋值给整数变量

}
错误原因:

变量的类型与赋值的值类型不一致,Rust 是静态类型语言,编译时会严格检查类型匹配。

解决方案:
  1. 确保值的类型与变量类型一致:let x: i32 = 5;

  2. 若需要不同类型,进行合法的类型转换:

    fn main() {

    复制代码
    // 字符串转整数(需处理可能的转换失败,用unwrap()简化,实际场景需处理错误)
    
    let x: i32 = "5".parse().unwrap();
    
    println!("x的值:{}(类型:i32)", x);  // 正确:输出5

    }

  3. 检查是否混淆了相似类型(如char&stri32u32)。

八、Rust 变量实操技巧(零基础必备)

掌握以下技巧,能更高效、规范地使用 Rust 变量,避免常见问题。

8.1 优先使用类型推断,必要时显式指定类型

Rust 的类型推断能力很强,大部分场景下无需手动指定类型,可减少冗余代码;但在 "类型不明确" 或 "需要特定类型" 的场景下,必须显式指定类型,避免编译器推断错误。

推荐做法:
复制代码
fn main() {

   // 推荐:类型推断(清晰明确,无冗余)

   let age = 25;          // 自动推断为i32

   let height = 1.75;     // 自动推断为f64

   let name = "张三";      // 自动推断为\&str

  

   // 必要时显式指定类型(避免推断错误)

   let byte: u8 = 0;      // 需指定为u8,避免推断为i32

   let score: f32 = 95.5; // 需指定为f32,避免推断为f64

}

8.2 尽量使用不可变变量,仅在必要时用 mut

Rust 默认不可变的设计,是为了保障数据一致性和线程安全。在实际开发中,应尽量使用不可变变量,仅当需要动态修改变量值时,才添加mut关键字,这能减少意外修改导致的 bug。

推荐做法:
复制代码
fn main() {

   // 推荐:不可变变量(值无需修改)

   let username = "张三";

   let max\_age = 120;

  

   // 必要时用mut(值需要动态修改)

   let mut count = 0;

   for \_ in 0..5 {

       count += 1;  // 必须用mut才能修改

   }

   println!("计数结果:{}", count);

}

8.3 合理使用变量遮蔽,避免变量名冗余

当需要对变量值进行加工(如类型转换、值预处理)且希望保留变量名时,变量遮蔽是最佳选择,可避免定义 "x1、x2、x3" 等冗余的变量名。

推荐做法:
复制代码
fn main() {

   // 推荐:变量遮蔽,避免冗余变量名

   let input = "  123.45  ";    // 原始输入(带空格的字符串)

   let input = input.trim();    // 去空格(遮蔽旧input)

   let input: f64 = input.parse().unwrap();  // 转浮点数(遮蔽旧input)

   let input = input \* 2;       // 计算翻倍(遮蔽旧input)

  

   println!("最终结果:{}", input);  // 输出246.9

}
不推荐做法(冗余变量名):
复制代码
fn main() {

   // 不推荐:变量名冗余,可读性差

   let input\_str = "  123.45  ";

   let input\_trimmed = input\_str.trim();

   let input\_float: f64 = input\_trimmed.parse().unwrap();

   let input\_result = input\_float \* 2;

  

   println!("最终结果:{}", input\_result);

}

8.4 全局值优先用 const,避免用 static mut

对于全局固定值(如配置、常量),优先使用const(编译期安全,无内存风险);除非有 "全局可变状态" 的特殊需求(如全局计数器),否则避免使用static mut(需unsafe访问,有内存安全风险)。

推荐做法:
复制代码
// 推荐:全局常量(安全,编译期嵌入)

const API\_BASE\_URL: \&str = "https://api.example.com";

const MAX\_REQUESTS: u32 = 10;

fn main() {

   println!("API地址:{}", API\_BASE\_URL);

   println!("最大请求数:{}", MAX\_REQUESTS);

}

九、总结与后续学习方向

9.1 核心知识点总结

通过本文学习,你已掌握 Rust 变量的核心内容:

  1. 变量本质:不仅是存储数据的容器,更是内存安全的守护者,自动管理内存(分配与释放);

  2. 定义与初始化:必须初始化后才能使用,支持类型推断和显式类型标注;

  3. 可变性 :默认不可变,mut关键字实现可变,可变变量类型不能改变;

  4. 变量遮蔽 :用let重新定义同名变量,可改变类型,创建新变量遮蔽旧变量;

  5. 作用域与生命周期:作用域划分变量的生效范围,生命周期管理变量的存活时间,超出作用域自动释放内存;

  6. 常量与静态变量:常量是编译期已知的全局固定值,静态变量是运行时全局变量,需谨慎使用可变静态变量。

9.2 后续学习方向

Rust 变量是后续学习的基础,掌握变量后,可继续深入以下内容:

  1. 所有权(Ownership):Rust 的核心特性,解释变量如何管理内存,避免内存泄漏和数据竞争;

  2. 引用与借用(References & Borrowing):如何在不转移所有权的情况下访问变量,避免拷贝开销;

  3. 切片(Slices):对数组、字符串等复合类型的 "部分引用",是变量的延伸使用;

  4. 函数与参数:变量在函数间的传递方式(值传递、引用传递),与变量的可变性、所有权密切相关。

建议通过 "理论学习 + 代码实践" 结合的方式,多编写变量相关的代码(如类型转换、作用域控制、变量遮蔽),观察编译结果,加深对 Rust 变量设计理念的理解。

(注:文档部分内容可能由 AI 生成)

相关推荐
G_dou_4 小时前
智能指针完全指南
windows·rust
G_dou_7 小时前
并发编程基础
算法·rust
ai安歌9 小时前
【Rust编程:从新手到大师】 Rust 控制流深度详解
开发语言·算法·rust
G_dou_11 小时前
借用与引用实战
rust
The 旺11 小时前
【Rust实战】打造内存安全的网络代理:深入异步IO与并发编程
网络·安全·rust
RustCoder13 小时前
RustNet:使用 Rust 开发的跨平台网络监控工具
安全·rust·开源
Xxtaoaooo14 小时前
Rust Actix-web框架源码解析:基于Actor模型的高性能Web开发
rust·源码分析·高性能·并发安全·actix-web
鼓掌MVP14 小时前
Rust Web实战:构建高性能并发工具的艺术
开发语言·前端·rust·异步编程·内存安全·actix-web·高性能web服务
盒马盒马14 小时前
Rust:函数与控制流
开发语言·网络·rust