在这里插入图片描述

一、Rust 是什么?为什么要学它?

在开始之前,你可能会问:“又一门编程语言?我为什么要学 Rust?” 🤔

简单来说:

  • 🚀 快如闪电:运行速度堪比 C/C++
  • 🔒 超级安全:编译器会在你写代码时就帮你抓 bug
  • 💎 现代化:有包管理器、测试框架、文档工具等完善生态
  • 🌟 越来越火:被 Google、Microsoft、Amazon 等大厂广泛使用

好了,废话不多说,让我们正式开始!💪

二、环境搭建(3 分钟速成)

安装 Rust

打开终端(Mac/Linux)或命令提示符(Windows),输入:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

安装完成后,验证一下:

rustc --version   # 查看 Rust 编译器版本
cargo --version   # 查看 Cargo(包管理器)版本

创建第一个项目

cargo new hello_rust
cd hello_rust
cargo run

你会看到:Hello, world! 🎉

恭喜!你的第一个 Rust 程序运行成功了!

三、变量声明:理解 “不可变” 的魔法

3.1 为什么默认不可变?

这是 Rust 最独特的地方!在其他语言里,变量默认都是可以修改的。但 Rust 反其道而行之:默认不可变

fn main() {
    let x = 5;
    println!("x 的值是: {}", x);
}

让我们拆解这段代码:

  • fn main() - 程序的入口函数
  • let x = 5 - 声明一个不可变变量 x,值为 5
  • println! - 打印宏(注意有个感叹号!)

3.2 尝试修改会怎样?

fn main() {
    let x = 5;
    x = 10;  // ❌ 编译错误!
}

编译器会告诉你:

error[E0384]: cannot assign twice to immutable variable `x`

为什么要这样设计? 🧐

想象你在写一个大型程序,有 100 个地方用到变量 x。如果默认可变,你在某个角落改了 x,可能会导致其他 99 个地方出 bug!而 Rust 说:“嘿,如果你要改变量,必须明确告诉我!” 这就大大减少了意外错误。

3.3 我真的要改变量怎么办?

mut 关键字!

fn main() {
    let mut x = 5;
    println!("x 是: {}", x);     // 5
    
    x = 10;  // ✅ 现在可以了!
    println!("x 变成: {}", x);   // 10
}

人话版理解let 像是用胶水粘住了变量,let mut 则像是用夹子夹住,可以取下来再换!📌

3.4 常量:永远不变的值

const MAX_LEVEL: u32 = 100;

fn main() {
    println!("最大等级: {}", MAX_LEVEL);
}

常量 vs 变量:

特性 let const
可变性 可以加 mut 永远不可变
类型声明 可选 必须明确
命名规范 小写_下划线 大写_下划线
作用域 函数内 全局

3.5 变量遮蔽(Shadowing)

这是 Rust 的一个超酷特性!✨

fn main() {
    let x = 5;
    let x = x + 1;  // 创建一个新的 x,"遮蔽" 了旧的 x
    let x = x * 2;  // 再次遮蔽
    
    println!("x 是: {}", x);  // 12
}

与 mut 的区别

let mut x = 5;
x = x + 1;  // 修改同一个变量

// vs

let x = 5;
let x = x + 1;  // 创建新变量,遮蔽旧变量

遮蔽的好处:可以改变类型

let spaces = "   ";           // 字符串
let spaces = spaces.len();    // ✅ 现在是数字了!

但 mut 不行:

let mut spaces = "   ";
spaces = spaces.len();  // ❌ 错误!类型不能变

四、数据类型:Rust 的 “类型动物园”

4.1 整数类型

Rust 的整数类型非常细致:

fn main() {
    let a: i8 = -128;      // 8 位有符号整数
    let b: u8 = 255;       // 8 位无符号整数
    let c: i32 = -123456;  // 32 位有符号整数(默认)
    let d: u64 = 999999;   // 64 位无符号整数
    
    println!("a={}, b={}, c={}, d={}", a, b, c, d);
}

人话理解

  • i = integer(可以是负数)
  • u = unsigned(只能是正数或 0)
  • 后面的数字 = 位数(8、16、32、64、128)

实用技巧:数字可以加下划线提高可读性!

let big_number = 1_000_000;  // 比 1000000 好读多了!
let hex = 0xff;              // 十六进制
let binary = 0b1111_0000;    // 二进制

4.2 浮点数

fn main() {
    let pi: f32 = 3.14;      // 单精度
    let e = 2.71828;         // 默认是 f64(双精度)
    
    println!("π ≈ {}, e ≈ {}", pi, e);
}

4.3 布尔值

fn main() {
    let is_raining: bool = true;
    let is_sunny = false;
    
    if is_raining {
        println!("记得带伞!");
    }
}

4.4 字符

Rust 的字符支持 Unicode!🌍

fn main() {
    let letter: char = 'A';
    let emoji = '🦀';
    let chinese = '你';
    
    println!("字符: {}, {}, {}", letter, emoji, chinese);
}

注意:字符用单引号 ',字符串用双引号 "

4.5 字符串(最容易混淆的部分)

Rust 有两种字符串:

fn main() {
    let s1: &str = "Hello";           // 字符串字面量
    let s2: String = String::from("World");  // String 类型
    
    println!("{}, {}!", s1, s2);
}

简单记忆法

  • &str - 不可变的字符串切片,通常用于只读
  • String - 可增长的字符串,存在堆上
fn main() {
    let mut s = String::from("Hello");
    s.push_str(", world!");  // ✅ 可以修改
    println!("{}", s);       // Hello, world!
}

五、复合类型:把数据组合起来

5.1 元组(Tuple)

把不同类型的数据打包在一起:

fn main() {
    let person = ("小明", 25, 175.5);  // (姓名, 年龄, 身高)
    
    println!("姓名: {}", person.0);
    println!("年龄: {}", person.1);
    println!("身高: {}cm", person.2);
}

也可以解构:

fn main() {
    let (name, age, height) = ("小明", 25, 175.5);
    println!("{} 今年 {} 岁,身高 {}cm", name, age, height);
}

5.2 数组(Array)

固定长度,同一类型:

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    let first = numbers[0];
    let second = numbers[1];
    
    println!("第一个: {}, 第二个: {}", first, second);
}

创建重复元素的数组:

let zeros = [0; 5];  // [0, 0, 0, 0, 0]

六、打印输出:让程序"说话"

6.1 基础打印

fn main() {
    let name = "小王";
    let age = 20;
    
    println!("我叫{}", name);
    println!("我今年{}岁", age);
    println!("我叫{},今年{}岁", name, age);
}

6.2 位置参数

fn main() {
    println!("{0} + {1} = {2}", 1, 2, 3);
    println!("{1} - {0} = {2}", 1, 2, 1);  // 可以调换顺序
}

6.3 命名参数

fn main() {
    println!("{name} 今年 {age} 岁", name="小李", age=22);
}

6.4 调试打印

fn main() {
    let numbers = [1, 2, 3];
    println!("{:?}", numbers);     // [1, 2, 3]
    println!("{:#?}", numbers);    // 更漂亮的格式
}

6.5 格式化选项

fn main() {
    let pi = 3.14159265;
    
    println!("保留 2 位小数: {:.2}", pi);      // 3.14
    println!("十六进制: {:x}", 255);           // ff
    println!("二进制: {:b}", 10);              // 1010
    println!("左对齐: {:<10}", "hi");          // "hi        "
    println!("右对齐: {:>10}", "hi");          // "        hi"
}

七、函数定义:代码的 “积木块”

7.1 最简单的函数

fn say_hello() {
    println!("你好!");
}

fn main() {
    say_hello();
    say_hello();
    say_hello();
}

输出:

你好!
你好!
你好!

7.2 带参数的函数

fn greet(name: &str) {
    println!("你好,{}!", name);
}

fn main() {
    greet("小明");
    greet("小红");
}

重点:参数必须声明类型!

多个参数:

fn introduce(name: &str, age: u32, city: &str) {
    println!("我叫{},今年{}岁,来自{}", name, age, city);
}

fn main() {
    introduce("小王", 25, "北京");
}

7.3 有返回值的函数

这里是 Rust 最特别的地方!🌟

fn add(a: i32, b: i32) -> i32 {
    a + b  // ← 注意没有分号!
}

fn main() {
    let result = add(5, 3);
    println!("5 + 3 = {}", result);  // 8
}

关键点

  • -> i32 声明返回类型
  • 最后一行没有分号,就是返回值!

如果加了分号呢?

fn add(a: i32, b: i32) -> i32 {
    a + b;  // ❌ 加了分号,这是语句,不返回值!
}

编译器会报错:

error[E0308]: mismatched types
expected `i32`, found `()`

人话解释

  • 没有分号 = 表达式(有值)
  • 有分号 = 语句(没有值)

7.4 显式 return

当然,你也可以用 return 关键字:

fn add(a: i32, b: i32) -> i32 {
    return a + b;  // 显式返回
}

什么时候用 return?通常是提前返回

fn divide(a: i32, b: i32) -> i32 {
    if b == 0 {
        return 0;  // 提前返回
    }
    a / b
}

7.5 多返回值(用元组)

fn get_coordinates() -> (i32, i32) {
    (100, 200)  // 返回元组
}

fn main() {
    let (x, y) = get_coordinates();
    println!("坐标: ({}, {})", x, y);
}

实用例子:

fn divide_with_remainder(a: i32, b: i32) -> (i32, i32) {
    (a / b, a % b)  // 返回商和余数
}

fn main() {
    let (quotient, remainder) = divide_with_remainder(17, 5);
    println!("17 ÷ 5 = {} 余 {}", quotient, remainder);
    // 输出:17 ÷ 5 = 3 余 2
}

7.6 无返回值函数

fn print_separator() {
    println!("====================");
}

fn main() {
    print_separator();
    println!("这是内容");
    print_separator();
}

实际上,无返回值函数返回的是 ()(单元类型)。

八、控制流:让程序做决定

8.1 if 表达式

fn main() {
    let age = 18;
    
    if age >= 18 {
        println!("你是成年人");
    } else {
        println!("你还未成年");
    }
}

注意:条件不需要括号!(和 C/Java 不同)

多个条件:

fn main() {
    let score = 85;
    
    if score >= 90 {
        println!("优秀");
    } else if score >= 80 {
        println!("良好");
    } else if score >= 60 {
        println!("及格");
    } else {
        println!("不及格");
    }
}

if 作为表达式:

fn main() {
    let number = 5;
    let message = if number > 0 {
        "正数"
    } else if number < 0 {
        "负数"
    } else {
        "零"
    };
    
    println!("这是一个{}", message);
}

8.2 循环

loop - 无限循环

fn main() {
    let mut count = 0;
    
    loop {
        count += 1;
        println!("计数: {}", count);
        
        if count == 5 {
            break;  // 跳出循环
        }
    }
}

while - 条件循环

fn main() {
    let mut number = 3;
    
    while number > 0 {
        println!("{}!", number);
        number -= 1;
    }
    println!("发射!🚀");
}

for - 遍历循环

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    
    for num in numbers {
        println!("数字: {}", num);
    }
}

范围循环:

fn main() {
    for i in 1..6 {  // 1 到 5(不包括 6)
        println!("{}", i);
    }
    
    for i in 1..=5 {  // 1 到 5(包括 5)
        println!("{}", i);
    }
}

九、常见错误与解决方案

错误 1:忘记声明参数类型 ❌

fn add(x, y) -> i32 {  // ❌ 错误!
    x + y
}

✅ 正确:

fn add(x: i32, y: i32) -> i32 {
    x + y
}

错误 2:混淆表达式和语句 ❌

fn get_number() -> i32 {
    let x = 5;  // ❌ 语句,没有返回值
}

✅ 正确:

fn get_number() -> i32 {
    5  // ✅ 表达式,有返回值
}

错误 3:修改不可变变量 ❌

let x = 5;
x = 10;  // ❌ 错误

✅ 正确:

let mut x = 5;
x = 10;  // ✅ 正确

十、小结

变量声明letmutconst、变量遮蔽
数据类型:整数、浮点数、布尔、字符、字符串
复合类型:元组、数组
打印输出println! 和格式化
函数定义:参数、返回值、表达式 vs 语句
控制流:if、loop、while、for


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐