Rust基本语法

一、Rust基础概述

1.1 语法设计目标

  • 安全、并发、性能并重,静态强类型与零成本抽象。
  • 表达式为核心,尽量在编译期发现问题。
  • 生态与工具链:rustup 管理工具链,cargo 构建与依赖管理,rust-analyzer 提升 IDE 体验。

1.2 程序基本结构

arduino 复制代码
fn main() {
    println!("Hello, Rust");
}

二、变量、所有权与借用

2.1 变量、常量与遮蔽

讲解:变量默认不可变,使用 mut 声明可变变量;遮蔽允许用同名新绑定覆盖旧值但保持不可变语义;const 为编译期常量,需显式类型。

示例:完整可执行的变量、遮蔽与常量演示

ini 复制代码
fn main() {
    let x = 1;
    let x = x + 1;
    let mut y = 0;
    y += 1;
    const MAX: u32 = 100_000;
    println!("x={}", x);
    println!("y={}", y);
    println!("MAX={}", MAX);
}

2.2 所有权、移动、复制与克隆

讲解:String 等堆分配类型在赋值时会发生所有权移动;clone 执行深拷贝保留两个独立所有权;诸如整数等实现 Copy 的标量类型按值复制,无需移动。

示例:完整可执行的所有权与克隆演示

rust 复制代码
fn main() {
    let s = String::from("hi");
    let t = s;
    println!("moved: {}", t);
    let u = t.clone();
    println!("cloned: t={}, u={}", t, u);

    let a = 1;
    let b = a;
    println!("copy: a={}, b={}", a, b);
}

2.3 借用与可变借用

讲解:不可变借用允许只读访问;可变借用在同一时刻只能存在一个以保证数据一致性;借用不转移所有权。

示例:完整可执行的借用演示

rust 复制代码
fn len(s: &String) -> usize { s.len() }
fn push_exclaim(s: &mut String) { s.push_str("!") }

fn main() {
    let mut s = String::from("a");
    let l = len(&s);
    println!("len={}", l);
    push_exclaim(&mut s);
    println!("{}", s);
}

2.4 切片与字符串

讲解:切片是对集合的只读视图,不拥有数据;字符串切片按字节索引,需保证落在 UTF-8 字符边界。

示例:完整可执行的切片演示

ini 复制代码
fn main() {
    let a = [1, 2, 3, 4];
    let slice = &a[1..3];
    println!("{:?}", slice);

    let s = String::from("hello");
    let r: &str = &s[0..2];
    println!("{}", r);
}

三、类型与数据结构

3.1 基本类型、元组、数组与切片

讲解:Rust 的标量与复合类型具备显式类型与固定大小;数组在栈上分配、长度固定;切片为只读视图。

示例:完整可执行的类型演示

rust 复制代码
fn main() {
    let i: i32 = -1;
    let f: f64 = 3.14;
    let b: bool = true;
    let c: char = '中';
    let tup: (i32, &str) = (7, "a");
    let (n, s) = tup;
    let arr: [i32; 3] = [1, 2, 3];
    let slice: &[i32] = &arr[..];
    println!("i={}, f={}, b={}, c={}", i, f, b, c);
    println!("tup=({}, {})", n, s);
    println!("arr={:?}", arr);
    println!("slice={:?}", slice);
}

3.2 String 与 &str

讲解:String 可变且拥有堆数据;&str 为只读借用的字符串视图;两者互补使用。

示例:完整可执行的字符串演示

rust 复制代码
fn main() {
    let mut s = String::from("hi");
    s.push_str("!");
    let r: &str = &s;
    println!("String={}", s);
    println!("&str={}", r);
}

3.3 结构体与实现

讲解:struct 定义数据结构,impl 块中可添加关联函数与方法;方法的第一个参数为接收者 &self&mut self

示例:完整可执行的结构体方法演示

rust 复制代码
struct Point { x: i32, y: i32 }
impl Point {
    fn new(x: i32, y: i32) -> Self { Self { x, y } }
    fn norm(&self) -> f64 { ((self.x.pow(2) + self.y.pow(2)) as f64).sqrt() }
}

fn main() {
    let p = Point::new(3, 4);
    println!("{}", p.norm());
}

3.4 枚举与模式匹配

讲解:enum 可表达代数数据类型;match 覆盖所有分支并支持解构与条件守卫。

示例:完整可执行的枚举匹配演示

rust 复制代码
enum Shape { Circle(f64), Rect { w: i32, h: i32 } }
fn area(s: Shape) -> f64 {
    match s {
        Shape::Circle(r) => 3.14159 * r * r,
        Shape::Rect { w, h } => (w * h) as f64,
    }
}

fn main() {
    let c = Shape::Circle(2.0);
    let r = Shape::Rect { w: 3, h: 4 };
    println!("{}", area(c));
    println!("{}", area(r));
}

3.5 Option 与 Result

讲解:Option 表示可空值,促使显式处理缺失情况;Result 表示可能出错的操作,结合 match? 传播错误。

示例:完整可执行的 Option 与 Result 演示

rust 复制代码
fn find(v: &[i32], x: i32) -> Option<usize> {
    for (i, n) in v.iter().enumerate() {
        if *n == x { return Some(i); }
    }
    None
}

fn main() {
    let v = vec![1, 2, 3];
    match find(&v, 2) {
        Some(i) => println!("found at {}", i),
        None => println!("not found"),
    }

    let ok = "42".parse::<i32>();
    let err = "x".parse::<i32>();
    match ok { Ok(n) => println!("ok {}", n), Err(e) => println!("error {}", e) }
    match err { Ok(n) => println!("ok {}", n), Err(e) => println!("error {}", e) }
}

四、函数、控制流与闭包

4.1 函数与返回值

讲解:函数返回值以尾表达式形式出现,无需 return;类型推断在参数位置较保守,需显式类型。

示例:完整可执行的函数演示

rust 复制代码
fn add(a: i32, b: i32) -> i32 { a + b }

fn main() {
    let r = add(2, 3);
    println!("{}", r);
}

4.2 控制流

讲解:if 是表达式可赋值;for 基于迭代器;loop 可构建无限循环并通过 break 退出。

示例:完整可执行的控制流演示

ini 复制代码
fn main() {
    let x = if true { 1 } else { 2 };
    println!("{}", x);
    for i in 0..3 { println!("{}", i); }
    let mut n = 0;
    while n < 3 { n += 1; println!("{}", n); }
    let mut k = 0;
    loop {
        k += 1;
        if k == 2 { break; }
    }
    println!("{}", k);
}

4.3 match 与 if let / while let

讲解:match 要覆盖所有可能分支;if letwhile let 简化对特定模式的处理。

示例:完整可执行的模式演示

scss 复制代码
fn main() {
    let v = Some(1);
    match v {
        Some(n) if n > 0 => println!("positive"),
        Some(_) => println!("non-positive"),
        None => println!("none"),
    }
    if let Some(n) = v { println!("{}", n); }

    let mut it = Some(0);
    while let Some(n) = it {
        if n == 2 { it = None; } else { it = Some(n + 1); }
        println!("{}", n);
    }
}

4.4 闭包与捕获

讲解:闭包可自动推断参数与返回类型,并按需以不可变/可变/按值捕获环境变量。

示例:完整可执行的闭包演示

ini 复制代码
fn main() {
    let mut n = 0;
    let mut f = |x: i32| { n += x; n };
    println!("{}", f(2));
    println!("{}", f(3));

    let v = vec![1, 2, 3];
    let s: i32 = v.iter().map(|x| x * 2).sum();
    println!("{}", s);
}

五、模块、泛型、生命周期与并发

5.1 模块与包结构

讲解:mod 定义子模块,pub 决定对外可见性;use 简化路径;二进制 crate 入口为 main.rs。示例以内联模块展示。

示例:完整可执行的模块演示

rust 复制代码
mod utils {
    pub fn greet(name: &str) -> String { format!("Hello, {}", name) }
}
fn main() {
    let s = utils::greet("Rust");
    println!("{}", s);
}

5.2 Trait 与泛型

讲解:Trait 描述行为接口;泛型结合 trait bounds 实现约束;零成本抽象避免运行时开销。

示例:完整可执行的 trait 与泛型演示

rust 复制代码
trait Area { fn area(&self) -> f64; }
struct Circle { r: f64 }
struct Rect { w: f64, h: f64 }
impl Area for Circle { fn area(&self) -> f64 { 3.14159 * self.r * self.r } }
impl Area for Rect { fn area(&self) -> f64 { self.w * self.h } }
fn sum<T: std::ops::Add<Output=T> + Copy>(a: T, b: T) -> T { a + b }
fn print_area<T: Area>(s: &T) { println!("{}", s.area()); }

fn main() {
    let c = Circle { r: 2.0 };
    let r = Rect { w: 3.0, h: 4.0 };
    print_area(&c);
    print_area(&r);
    println!("{}", sum(1, 2));
    println!("{}", sum(1.5, 2.5));
}

5.3 生命周期

讲解:生命周期参数声明引用至少存活到返回值使用完;编译器借助省略规则自动推断多数场景。

示例:完整可执行的生命周期演示

rust 复制代码
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let a = String::from("abcd");
    let b = String::from("xyz");
    let r = longest(&a, &b);
    println!("{}", r);
}

5.4 集合与迭代器

讲解:集合位于标准库;迭代器链支持惰性计算与组合操作;HashMap 提供键值存储与借用访问。

示例:完整可执行的集合与迭代器演示

rust 复制代码
use std::collections::HashMap;

fn main() {
    let v = vec![1, 2, 3, 4];
    let even_sum: i32 = v.iter().filter(|n| *n % 2 == 0).sum();
    println!("{}", even_sum);

    let mut m = HashMap::new();
    m.insert("a", 1);
    m.insert("b", 2);
    if let Some(x) = m.get("a") { println!("{}", x); }
    for (k, v) in &m { println!("{} {}", k, v); }
}

5.5 智能指针与并发

讲解:Rc<T> 在单线程中实现共享所有权;并发下用 Arc<T> 提供原子引用计数,搭配 Mutex<T> 进行互斥访问;线程通过 spawn 创建并在 join 等待完成。

示例:完整可执行的智能指针与并发演示

rust 复制代码
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let a = Rc::new(String::from("x"));
    let b = Rc::clone(&a);
    println!("{} {}", a, b);

    let c = Arc::new(Mutex::new(0));
    let mut handles = vec![];
    for _ in 0..4 {
        let c2 = Arc::clone(&c);
        handles.push(thread::spawn(move || {
            let mut n = c2.lock().unwrap();
            *n += 1;
        }));
    }
    for h in handles { h.join().unwrap(); }
    println!("{}", *c.lock().unwrap());
}

5.6 代码质量与测试

讲解:cargo fmt 统一代码风格;cargo clippy 静态诊断建议;测试框架内置,使用 #[test] 标记。

示例:在同一文件中包含测试与可执行入口

rust 复制代码
#[cfg(test)]
mod tests {
    fn add(a: i32, b: i32) -> i32 { a + b }
    #[test]
    fn it_works() { assert_eq!(add(2, 2), 4); }
}

fn main() {
    println!("run `cargo test` to execute tests");
}

常用命令:

bash 复制代码
cargo fmt
cargo clippy
cargo test
相关推荐
蚂蚁背大象1 小时前
Rust 所有权系统是为了解决什么问题
后端·rust
子玖3 小时前
go实现通过ip解析城市
后端·go
Java不加班3 小时前
Java 后端定时任务实现方案与工程化指南
后端
心在飞扬3 小时前
RAG 进阶检索学习笔记
后端
Moment3 小时前
想要长期陪伴你的助理?先从部署一个 OpenClaw 开始 😍😍😍
前端·后端·github
Das1_3 小时前
【Golang 数据结构】Slice 底层机制
后端·go
得物技术3 小时前
深入剖析Spark UI界面:参数与界面详解|得物技术
大数据·后端·spark
古时的风筝3 小时前
花10 分钟时间,把终端改造成“生产力武器”:Ghostty + Yazi + Lazygit 配置全流程
前端·后端·程序员
Cache技术分享3 小时前
340. Java Stream API - 理解并行流的额外开销
前端·后端