【Rust】结构体(Struct)详解

结构体(struct)是 Rust 中自定义复合数据类型的主要方式,允许你将多个相关值组合在一起。

1. 基本结构体定义

定义和实例化

rust 复制代码
// 定义结构体
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

// 创建实例
let user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

// 访问字段
println!("用户名: {}", user1.username);
println!("邮箱: {}", user1.email);

可变结构体

rust 复制代码
let mut user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

// 修改字段值
user1.email = String::from("anotheremail@example.com");
user1.sign_in_count += 1;

2. 结构体更新语法

rust 复制代码
let user1 = User {
    email: String::from("user1@example.com"),
    username: String::from("user1"),
    active: true,
    sign_in_count: 1,
};

// 使用更新语法创建新实例
let user2 = User {
    email: String::from("user2@example.com"),
    username: String::from("user2"),
    ..user1  // 继承 user1 的其他字段
};

// user2 将拥有 user1 的 active 和 sign_in_count 值

3. 元组结构体

没有字段名,只有类型的结构体:

rust 复制代码
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);

// 通过索引访问
println!("红色分量: {}", black.0);
println!("x坐标: {}", origin.0);

// 即使字段类型相同,也是不同的类型
// let color: Color = origin; // 错误!类型不匹配

4. 类单元结构体

没有字段的结构体:

rust 复制代码
struct AlwaysEqual;

let subject = AlwaysEqual;

// 常用于 trait 实现或标记类型
impl AlwaysEqual {
    fn new() -> Self {
        AlwaysEqual
    }
}

5. 结构体方法

定义方法

rust 复制代码
struct Rectangle {
    width: u32,
    height: u32,
}

// 使用 impl 块定义方法
impl Rectangle {
    // 关联函数(类似静态方法)
    fn new(width: u32, height: u32) -> Self {
        Rectangle { width, height }
    }
    
    // 实例方法
    fn area(&self) -> u32 {
        self.width * self.height
    }
    
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
    
    // 修改方法
    fn scale(&mut self, factor: f32) {
        self.width = (self.width as f32 * factor) as u32;
        self.height = (self.height as f32 * factor) as u32;
    }
    
    // 获取器(getter)
    fn width(&self) -> u32 {
        self.width
    }
    
    fn height(&self) -> u32 {
        self.height
    }
}

// 使用
let rect = Rectangle::new(30, 50);
println!("面积: {}", rect.area());

let mut rect2 = Rectangle::new(10, 20);
rect2.scale(1.5);

多个 impl 块

rust 复制代码
impl Rectangle {
    fn square(size: u32) -> Self {
        Rectangle { width: size, height: size }
    }
}

impl Rectangle {
    fn perimeter(&self) -> u32 {
        2 * (self.width + self.height)
    }
}

6. 关联函数 vs 方法

rust 复制代码
struct Circle {
    radius: f64,
}

impl Circle {
    // 关联函数 - 没有 self 参数
    fn new(radius: f64) -> Self {
        Circle { radius }
    }
    
    // 方法 - 有 self 参数
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
}

// 使用
let circle = Circle::new(5.0);  // 调用关联函数
let area = circle.area();       // 调用方法

7. 结构体与所有权

使用引用字段

rust 复制代码
struct User<'a> {
    username: &'a str,      // 字符串切片引用
    email: &'a str,
    sign_in_count: u64,
}

let username = "john_doe";
let email = "john@example.com";
let user = User {
    username,
    email,
    sign_in_count: 1,
};

使用 String(拥有所有权)

rust 复制代码
struct OwnedUser {
    username: String,      // 拥有字符串所有权
    email: String,
    sign_in_count: u64,
}

8. Debug 打印

rust 复制代码
#[derive(Debug)]  // 自动实现 Debug trait
struct Point {
    x: i32,
    y: i32,
}

let point = Point { x: 10, y: 20 };
println!("{:?}", point);     // 调试输出: Point { x: 10, y: 20 }
println!("{:#?}", point);    // 美化输出
// Point {
//     x: 10,
//     y: 20,
// }

9. 结构体模式匹配

rust 复制代码
struct Point {
    x: i32,
    y: i32,
}

let point = Point { x: 10, y: 20 };

// 解构结构体
let Point { x, y } = point;
println!("x: {}, y: {}", x, y);

// 模式匹配
match point {
    Point { x: 0, y: 0 } => println!("原点"),
    Point { x, y: 0 } => println!("x轴上的点: {}", x),
    Point { x: 0, y } => println!("y轴上的点: {}", y),
    Point { x, y } => println!("点({}, {})", x, y),
}

10. 常用 trait 派生

rust 复制代码
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Point {
    x: i32,
    y: i32,
}

#[derive(Debug, Default)]
struct Config {
    timeout: u32,
    retries: u32,
}

// 使用默认值
let config = Config::default();  // timeout: 0, retries: 0

11. 泛型结构体

rust 复制代码
// 泛型结构体
struct Pair<T, U> {
    first: T,
    second: U,
}

// 使用
let integer_pair = Pair { first: 5, second: 10 };
let mixed_pair = Pair { first: "hello", second: 42.5 };

// 泛型方法实现
impl<T, U> Pair<T, U> {
    fn new(first: T, second: U) -> Self {
        Pair { first, second }
    }
    
    fn swap(self) -> Pair<U, T> {
        Pair {
            first: self.second,
            second: self.first,
        }
    }
}

12. Newtype 模式

使用元组结构体创建新类型:

rust 复制代码
struct Kilometers(i32);
struct Meters(i32);

let distance1 = Kilometers(5);
let distance2 = Meters(5000);

// 这样不会意外混淆不同类型
// let total = distance1 + distance2; // 编译错误!

13. 结构体最佳实践

  1. 命名规范:使用大驼峰命名法
  2. 字段访问:考虑提供 getter/setter
  3. 不可变性:优先使用不可变结构体
  4. 所有权:根据需求选择引用或拥有所有权
  5. 文档注释:为公共结构体添加文档
rust 复制代码
/// 表示一个二维点
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Point {
    /// x 坐标
    pub x: f64,
    /// y 坐标
    pub y: f64,
}

impl Point {
    /// 创建新点
    pub fn new(x: f64, y: f64) -> Self {
        Point { x, y }
    }
    
    /// 计算到原点的距离
    pub fn distance_from_origin(&self) -> f64 {
        (self.x * self.x + self.y * self.y).sqrt()
    }
}

14. 结构体 vs 枚举 vs 元组

特性 结构体 枚举 元组
字段名
变体 有多个
访问 点号 模式匹配 索引
用途 数据聚合 选择分支 简单组合

总结

Rust 结构体提供了:

  • 数据封装:将相关数据组合在一起
  • 类型安全:编译时检查字段访问
  • 方法封装:将数据与操作绑定
  • 灵活性:支持泛型、生命周期等
  • 模式匹配:强大的解构能力

结构体是 Rust 面向数据编程的核心,结合枚举和 trait,构成了 Rust 强大的类型系统。

复制代码
相关推荐
DongLi012 天前
rustlings 学习笔记 -- exercises/05_vecs
rust
番茄灭世神3 天前
Rust学习笔记第2篇
rust·编程语言
shimly1234563 天前
(done) 速通 rustlings(20) 错误处理1 --- 不涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(19) Option
rust
@atweiwei3 天前
rust所有权机制详解
开发语言·数据结构·后端·rust·内存·所有权
shimly1234563 天前
(done) 速通 rustlings(24) 错误处理2 --- 涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(23) 特性 Traits
rust
shimly1234563 天前
(done) 速通 rustlings(17) 哈希表
rust
shimly1234563 天前
(done) 速通 rustlings(15) 字符串
rust
shimly1234563 天前
(done) 速通 rustlings(22) 泛型
rust