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
相关推荐
Python私教2 小时前
Rust环境搭建
后端
jakeswang2 小时前
ServletLess架构简介
java·后端·servletless
夕颜1112 小时前
如何让 AI 按照你的预期输出
后端
q***56383 小时前
Spring Boot--@PathVariable、@RequestParam、@RequestBody
java·spring boot·后端
q***57504 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端
猪猪拆迁队4 小时前
前端图形引擎架构设计:双引擎架构设计
前端·后端·架构
GISer_Jing5 小时前
Node.js 开发实战:从入门到精通
javascript·后端·node.js
q***51895 小时前
Spring Boot 条件注解:@ConditionalOnProperty 完全解析
java·spring boot·后端
码事漫谈6 小时前
C/C++混合项目中的头文件管理:.h与.hpp的分工与协作
后端