在 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);
}
在这个例子中,user2
的 email
字段被赋予了新的值,其他字段的值与 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
,表示对结构体实例的不可变引用。
通过结构体,可以将相关的数据和操作组织在一起,提高代码的可读性和可维护性。