Rust 结构体

118 阅读3分钟

在 Rust 中,结构体(Struct)是一种自定义的数据类型,它允许你将多个不同类型的值组合在一起,形成一个有意义的集合。结构体在组织和管理数据方面非常有用,下面从结构体的定义、实例化、方法定义和使用等方面详细介绍。

结构体的定义

使用 struct 关键字来定义结构体,结构体可以包含多个字段(Field),每个字段都有一个名称和对应的类型。以下是三种常见的结构体定义形式:

普通结构体

// 定义一个表示用户信息的结构体 
struct User { 
    username: String, 
    email: String, 
    sign_in_count: u64, 
    active: bool, 
} 

在上述代码中,定义了一个名为 User 的结构体,它包含四个字段:username(字符串类型)、email(字符串类型)、sign_in_count(无符号 64 位整数类型)和 active(布尔类型)。

元组结构体

元组结构体类似于元组,它有一个名称,但字段没有具体的名称,只有类型。

// 定义一个表示 RGB 颜色的元组结构体 
struct Color(i32, i32, i32); 

这里定义了一个名为 Color 的元组结构体,它包含三个 i32 类型的字段。

单元结构体

单元结构体没有任何字段,类似于空元组 ()

// 定义一个单元结构体 
struct AlwaysEqual; 

结构体的实例化

定义好结构体后,可以创建结构体的实例。实例化时需要为每个字段提供对应的值。

普通结构体实例化

struct User { 
    username: String, 
    email: String, 
    sign_in_count: u64, 
    active: bool, 
} 
fn main() { 
    let user1 = User { 
        username: String::from("john_doe"), 
        email: String::from("john@example.com"), 
        sign_in_count: 1, 
        active: true, 
    }; 
    println!("User email: {}", user1.email); 
} 

main 函数中,创建了 User 结构体的一个实例 user1,并为每个字段赋值。可以使用点号(.)来访问结构体实例的字段。

元组结构体实例化

struct Color(i32, i32, i32); 
fn main() { 
    let black = Color(0, 0, 0); 
    println!("Red value: {}", black.0); 
} 

这里创建了 Color 元组结构体的一个实例 black,并使用索引(从 0 开始)来访问元组结构体的字段。

结构体更新语法

当创建一个新的结构体实例时,如果部分字段的值与已有的实例相同,可以使用结构体更新语法来简化代码。

struct User { 
    username: String,
    email: String, 
    sign_in_count: u64, 
    active: bool, 
} 
fn main() { 
    let user1 = User { 
        username: String::from("john_doe"), 
        email: String::from("john@example.com"), 
        sign_in_count: 1, 
        active: true, 
    }; 
    let user2 = User { 
        email: String::from("jane@example.com"), 
        ..user1 
    }; 
    println!("User 2 username: {}", user2.username); 
} 

在这个例子中,user2email 字段被赋予了新的值,其他字段的值与 user1 相同,使用 ..user1 来表示复用 user1 的其他字段值。

结构体方法

结构体可以拥有方法(Method),方法是与结构体关联的函数,它可以访问和修改结构体的字段。使用 impl 块来定义结构体的方法。

struct Rectangle { 
    width: u32, 
    height: u32, 
} 
impl Rectangle { 
    // 定义一个方法来计算矩形的面积 
    fn area(&self) -> u32 { 
        self.width * self.height 
    } 
    // 定义一个方法来判断矩形是否能包含另一个矩形 
    fn can_hold(&self, other: &Rectangle) -> bool { 
        self.width > other.width && self.height > other.height 
    } 
} 

fn main() { 
    let rect1 = Rectangle { 
        width: 30, 
        height: 50 
    }; 
    let rect2 = Rectangle { 
        width: 10, 
        height: 40 
    }; 
    println!("The area of rect1 is {}", rect1.area()); 
    println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); 
} 

在上述代码中,impl Rectangle 块为 Rectangle 结构体定义了两个方法:area 方法用于计算矩形的面积,can_hold 方法用于判断一个矩形是否能包含另一个矩形。方法的第一个参数通常是 &self,表示对结构体实例的不可变引用。

通过结构体,可以将相关的数据和操作组织在一起,提高代码的可读性和可维护性。