Skip to content

Rust 快速上手

概述

本章通过实际的代码示例,让你快速了解 Rust 的基本语法和核心概念。我们将从 Hello World 开始,逐步构建更复杂的程序。

🚀 Hello World

第一个程序

rust
// src/main.rs
fn main() {
    println!("Hello, World!");
    println!("你好,Rust!");
    
    // 格式化输出
    let name = "Rust";
    let year = 2023;
    println!("欢迎来到 {} 世界!现在是 {} 年。", name, year);
}
bash
# 运行程序
cargo run
# 输出:
# Hello, World!
# 你好,Rust!
# 欢迎来到 Rust 世界!现在是 2023 年。

变量和常量

rust
fn main() {
    // 不可变变量(默认)
    let x = 5;
    println!("x 的值是: {}", x);
    
    // x = 6; // 编译错误!不可变变量不能重新赋值
    
    // 可变变量
    let mut y = 5;
    println!("y 的值是: {}", y);
    y = 6; // 可以修改
    println!("现在 y 的值是: {}", y);
    
    // 变量遮蔽(shadowing)
    let x = x + 1; // 创建新变量,遮蔽之前的 x
    println!("遮蔽后 x 的值是: {}", x);
    
    // 常量
    const MAX_POINTS: u32 = 100_000;
    println!("最大分数: {}", MAX_POINTS);
}

📊 基本数据类型

数值类型

rust
fn number_types() {
    // 整数类型
    let small: i8 = -128;
    let big: i64 = 1_000_000;
    let unsigned: u32 = 42;
    
    // 浮点类型
    let pi: f64 = 3.14159;
    let e: f32 = 2.71828;
    
    // 类型推断
    let guess = 42; // 默认 i32
    let float_guess = 3.14; // 默认 f64
    
    println!("整数: {}, {}, {}", small, big, unsigned);
    println!("浮点: {}, {}", pi, e);
    println!("推断: {}, {}", guess, float_guess);
}

布尔和字符类型

rust
fn bool_and_char() {
    // 布尔类型
    let is_rust_awesome = true;
    let is_difficult: bool = false;
    
    // 字符类型(Unicode)
    let letter = 'A';
    let emoji = '😀';
    let chinese = '中';
    
    println!("布尔值: {}, {}", is_rust_awesome, is_difficult);
    println!("字符: {}, {}, {}", letter, emoji, chinese);
}

复合类型

rust
fn compound_types() {
    // 元组
    let tuple: (i32, f64, char) = (42, 3.14, 'R');
    let (x, y, z) = tuple; // 解构
    println!("元组: {}, {}, {}", x, y, z);
    println!("访问元组: {}", tuple.0);
    
    // 数组
    let array = [1, 2, 3, 4, 5];
    let months = ["一月", "二月", "三月"];
    let zeros = [0; 5]; // [0, 0, 0, 0, 0]
    
    println!("数组: {:?}", array);
    println!("第一个月: {}", months[0]);
    println!("全零数组: {:?}", zeros);
}

🔧 函数基础

函数定义和调用

rust
fn main() {
    println!("主函数开始");
    
    // 调用函数
    greet();
    let result = add(5, 3);
    println!("5 + 3 = {}", result);
    
    // 带返回值的函数
    let (sum, product) = calculate(4, 6);
    println!("4 + 6 = {}, 4 * 6 = {}", sum, product);
}

// 无参数无返回值
fn greet() {
    println!("你好,来自函数的问候!");
}

// 有参数有返回值
fn add(a: i32, b: i32) -> i32 {
    a + b // 表达式,没有分号
}

// 多个返回值(使用元组)
fn calculate(x: i32, y: i32) -> (i32, i32) {
    (x + y, x * y)
}

// 带语句的函数
fn verbose_add(a: i32, b: i32) -> i32 {
    println!("计算 {} + {}", a, b);
    let result = a + b; // 语句
    result // 表达式
}

🎛️ 控制流

条件语句

rust
fn conditionals() {
    let number = 6;
    
    // if 表达式
    if number % 4 == 0 {
        println!("{} 能被 4 整除", number);
    } else if number % 3 == 0 {
        println!("{} 能被 3 整除", number);
    } else if number % 2 == 0 {
        println!("{} 能被 2 整除", number);
    } else {
        println!("{} 不能被 2、3、4 整除", number);
    }
    
    // if 表达式赋值
    let condition = true;
    let result = if condition { 5 } else { 6 };
    println!("结果是: {}", result);
    
    // 复杂条件
    let age = 18;
    let has_license = true;
    
    if age >= 18 && has_license {
        println!("可以开车");
    } else {
        println!("不能开车");
    }
}

循环

rust
fn loops() {
    // loop 无限循环
    let mut counter = 0;
    loop {
        counter += 1;
        if counter == 3 {
            println!("跳过 3");
            continue;
        }
        if counter == 6 {
            println!("结束循环");
            break;
        }
        println!("计数器: {}", counter);
    }
    
    // while 条件循环
    let mut number = 3;
    while number != 0 {
        println!("倒计时: {}", number);
        number -= 1;
    }
    println!("发射!");
    
    // for 迭代循环
    let array = [10, 20, 30, 40, 50];
    for element in array.iter() {
        println!("值是: {}", element);
    }
    
    // 范围循环
    for number in 1..4 {
        println!("数字: {}", number);
    }
    
    // 带索引的循环
    for (index, value) in array.iter().enumerate() {
        println!("索引 {} 的值是 {}", index, value);
    }
}

📦 所有权入门

基本所有权

rust
fn ownership_basics() {
    // 所有权转移
    let s1 = String::from("hello");
    let s2 = s1; // s1 的所有权转移给 s2
    
    // println!("{}", s1); // 编译错误!s1 已失效
    println!("{}", s2); // 正常
    
    // 克隆
    let s3 = String::from("world");
    let s4 = s3.clone(); // 深拷贝
    println!("s3: {}, s4: {}", s3, s4); // 都有效
    
    // 基本类型的复制
    let x = 5;
    let y = x; // Copy trait,两个都有效
    println!("x: {}, y: {}", x, y);
}

fn ownership_functions() {
    let s = String::from("hello");
    takes_ownership(s); // s 的值移动到函数里
    // println!("{}", s); // 编译错误!s 已失效
    
    let x = 5;
    makes_copy(x); // i32 是 Copy 的,所以 x 仍然有效
    println!("{}", x); // 正常
    
    let s1 = gives_ownership(); // 函数返回值移动给 s1
    println!("{}", s1);
    
    let s2 = String::from("world");
    let s3 = takes_and_gives_back(s2); // s2 移动到函数,返回值移动给 s3
    println!("{}", s3);
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
} // some_string 离开作用域并被丢弃

fn makes_copy(some_integer: i32) {
    println!("{}", some_integer);
} // some_integer 离开作用域,没有特殊操作

fn gives_ownership() -> String {
    let some_string = String::from("hello");
    some_string // 返回,所有权移动到调用函数
}

fn takes_and_gives_back(a_string: String) -> String {
    a_string // 返回,所有权移动到调用函数
}

引用和借用

rust
fn references_and_borrowing() {
    let s1 = String::from("hello");
    
    // 不可变引用
    let len = calculate_length(&s1);
    println!("'{}' 的长度是 {}", s1, len); // s1 仍然有效
    
    // 可变引用
    let mut s2 = String::from("hello");
    change(&mut s2);
    println!("修改后: {}", s2);
    
    // 多个不可变引用
    let r1 = &s1;
    let r2 = &s1;
    println!("{} 和 {}", r1, r2); // 正常
    
    // 可变引用的限制
    let mut s3 = String::from("hello");
    let r3 = &mut s3;
    // let r4 = &mut s3; // 编译错误!同时只能有一个可变引用
    println!("{}", r3);
}

fn calculate_length(s: &String) -> usize {
    s.len()
} // s 离开作用域,但因为它不拥有引用值的所有权,所以什么都不会发生

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

🏗️ 结构体入门

定义和使用结构体

rust
// 定义结构体
#[derive(Debug)] // 允许使用 {:?} 格式化打印
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

// 元组结构体
#[derive(Debug)]
struct Point(i32, i32, i32);

fn struct_examples() {
    // 创建结构体实例
    let user1 = User {
        email: String::from("user@example.com"),
        username: String::from("someuser"),
        active: true,
        sign_in_count: 1,
    };
    
    println!("用户: {:?}", user1);
    println!("用户名: {}", user1.username);
    
    // 可变结构体
    let mut user2 = User {
        email: String::from("another@example.com"),
        username: String::from("anotherusername"),
        active: true,
        sign_in_count: 1,
    };
    
    user2.email = String::from("newemail@example.com");
    println!("更新后的邮箱: {}", user2.email);
    
    // 结构体更新语法
    let user3 = User {
        email: String::from("third@example.com"),
        username: String::from("thirduser"),
        ..user1 // 其余字段与 user1 相同
    };
    
    println!("用户3: {:?}", user3);
    
    // 元组结构体
    let point = Point(1, 2, 3);
    println!("点: {:?}", point);
    println!("x 坐标: {}", point.0);
}

// 关联函数和方法
impl User {
    // 关联函数(类似静态方法)
    fn new(email: String, username: String) -> User {
        User {
            email,
            username,
            active: true,
            sign_in_count: 1,
        }
    }
    
    // 方法
    fn is_active(&self) -> bool {
        self.active
    }
    
    fn deactivate(&mut self) {
        self.active = false;
    }
    
    fn activate(&mut self) {
        self.active = true;
        self.sign_in_count += 1;
    }
}

fn struct_methods() {
    // 使用关联函数
    let mut user = User::new(
        String::from("test@example.com"),
        String::from("testuser")
    );
    
    println!("用户活跃状态: {}", user.is_active());
    
    user.deactivate();
    println!("停用后状态: {}", user.is_active());
    
    user.activate();
    println!("激活后状态: {}, 登录次数: {}", user.is_active(), user.sign_in_count);
}

🎯 枚举和匹配

枚举定义

rust
#[derive(Debug)]
enum IpAddrKind {
    V4,
    V6,
}

#[derive(Debug)]
enum IpAddr {
    V4(u8, u8, u8, u8),
    V6(String),
}

#[derive(Debug)]
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn enum_examples() {
    // 基本枚举
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;
    
    println!("IP 版本: {:?}, {:?}", four, six);
    
    // 带数据的枚举
    let home = IpAddr::V4(127, 0, 0, 1);
    let loopback = IpAddr::V6(String::from("::1"));
    
    println!("IP 地址: {:?}, {:?}", home, loopback);
    
    // 复杂枚举
    let messages = vec![
        Message::Quit,
        Message::Move { x: 10, y: 20 },
        Message::Write(String::from("Hello")),
        Message::ChangeColor(255, 0, 0),
    ];
    
    for msg in messages {
        process_message(msg);
    }
}

fn process_message(msg: Message) {
    match msg {
        Message::Quit => println!("退出程序"),
        Message::Move { x, y } => println!("移动到坐标 ({}, {})", x, y),
        Message::Write(text) => println!("写入文本: {}", text),
        Message::ChangeColor(r, g, b) => println!("改变颜色为 RGB({}, {}, {})", r, g, b),
    }
}

Option 和 Result

rust
fn option_examples() {
    // Option 枚举
    let some_number = Some(5);
    let some_string = Some("字符串");
    let absent_number: Option<i32> = None;
    
    println!("有值: {:?}, {:?}", some_number, some_string);
    println!("无值: {:?}", absent_number);
    
    // 处理 Option
    match some_number {
        Some(value) => println!("找到值: {}", value),
        None => println!("没有值"),
    }
    
    // if let 简化匹配
    if let Some(value) = some_number {
        println!("if let 找到值: {}", value);
    }
    
    // unwrap_or 提供默认值
    let default_value = absent_number.unwrap_or(0);
    println!("默认值: {}", default_value);
}

fn result_examples() {
    // Result 用于错误处理
    let good_result: Result<i32, &str> = Ok(10);
    let bad_result: Result<i32, &str> = Err("出错了");
    
    match good_result {
        Ok(value) => println!("成功: {}", value),
        Err(error) => println!("错误: {}", error),
    }
    
    match bad_result {
        Ok(value) => println!("成功: {}", value),
        Err(error) => println!("错误: {}", error),
    }
    
    // 链式操作
    let result = divide(10, 2)
        .and_then(|x| divide(x, 2))
        .and_then(|x| divide(x, 0)); // 这里会出错
    
    match result {
        Ok(value) => println!("最终结果: {}", value),
        Err(error) => println!("计算错误: {}", error),
    }
}

fn divide(dividend: i32, divisor: i32) -> Result<i32, String> {
    if divisor == 0 {
        Err("不能除以零".to_string())
    } else {
        Ok(dividend / divisor)
    }
}

🎬 完整示例:猜数字游戏

rust
use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn guessing_game() {
    println!("猜数字游戏!");
    
    let secret_number = rand::thread_rng().gen_range(1..101);
    
    loop {
        println!("请输入你的猜测(1-100):");
        
        let mut guess = String::new();
        
        io::stdin()
            .read_line(&mut guess)
            .expect("读取输入失败");
        
        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("请输入有效数字!");
                continue;
            }
        };
        
        println!("你猜的数字是: {}", guess);
        
        match guess.cmp(&secret_number) {
            Ordering::Less => println!("太小了!"),
            Ordering::Greater => println!("太大了!"),
            Ordering::Equal => {
                println!("恭喜你,猜对了!");
                break;
            }
        }
    }
}

fn main() {
    // 运行所有示例
    println!("=== 数据类型示例 ===");
    number_types();
    bool_and_char();
    compound_types();
    
    println!("\n=== 条件和循环示例 ===");
    conditionals();
    loops();
    
    println!("\n=== 所有权示例 ===");
    ownership_basics();
    ownership_functions();
    references_and_borrowing();
    
    println!("\n=== 结构体示例 ===");
    struct_examples();
    struct_methods();
    
    println!("\n=== 枚举示例 ===");
    enum_examples();
    option_examples();
    result_examples();
    
    println!("\n=== 猜数字游戏 ===");
    guessing_game();
}

📝 本章小结

通过本章学习,你应该掌握了:

Rust 基础

  • ✅ 变量、常量和基本数据类型
  • ✅ 函数定义和调用
  • ✅ 控制流(条件语句和循环)
  • ✅ 所有权、借用和引用的基本概念

核心特性

  • ✅ 结构体的定义和使用
  • ✅ 枚举和模式匹配
  • ✅ Option 和 Result 类型
  • ✅ 错误处理基础

实践经验

  • ✅ 完整的项目示例
  • ✅ 常见编程模式
  • ✅ Rust 特有的编程思维

继续学习下一章 - Rust 基础语法

本站内容仅供学习和研究使用。