结构体
约 841 字大约 3 分钟
2025-07-27
结构体是由多种类型组合而成的复合类型,定义一个结构体使用 struct 关键字,后接结构体的名字,之后使用 {} 进行包裹。
在 {} 中,定义的每个数据的名称和类型被称为 字段。字段之间使用 , 分隔
注
结构体名需要描述它所组合的数据的意义,并且使用大驼峰命名法
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}创建结构体实例
创建一个结构体实例需要以结构体的名字开头,接着在大括号中使用 key: value 键值对的形式提供字段,实例中字段的顺序并不需要与定义结构体时字段的顺序保持一致
let user1 = User {
active: true,
username: String::from("someusername123"),
email: String::from("someone@example.com"),
sign_in_count: 1,
};重要
- 实例化结构体时,每个字段都需要进行初始化
字段初始化的简化写法
在创建结构体实例时,如果字段名与字段值一致,可以直接将其简写
fn build_user(email: String, username: String) -> User {
User {
active: true,
email,
username,
sign_in_count: 1
}
}元组结构体
结构体必须要有名称,但是结构体的字段可以没有名称,这种结构体长得很像元组,因此被称为元组结构体
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);与元组不同的是,在解构元组结构体时,必须要写明结构体的类型
let Point(x, y, z) = origin;类单元结构体
类单元结构体没有任何字段和属性,当只关心该类型的行为时,就可以使用类单元结构体,后续再为其实现某个特征
struct AlwaysEqual;
let subject = AlwaysEqual;
// 我们不关心 AlwaysEqual 的字段数据,只关心它的行为,
// 因此将它声明为类单元结构体,然后再为它实现某个特征
impl SomeTrait for AlwaysEqual {}访问与修改结构体字段
访问结构体字段通过 . 操作符即可访问结构体内部实例的字段值,也可以修改字段值
重要
要修改结构体的字段值,必须要将结构体实例声明为可变的,Rust 不支持将某个结构体某个字段标记为可变
访问结构体字段与修改字段值
fn main() {
let mut user1 = User {
active: true,
email: String::from("someone@example.com"),
username: String::from("someusername123"),
sign_in_count: 1
};
// 访问字段
println!("user1 email is {}", user1.email);
// 修改值
user1.active = false;
println!("user1 active is {}", user1.active);
}结构体更新
结构体更新指的是:复用旧实例的大部分字段,但替换少量字段后,来创建一个新的结构体实例。语法为 ..,表示未显式设置的字段取自给定实例对应字段的值
结构体更新
#[derive(Debug)]
struct User {
active: bool,
email: String,
username: String,
sign_in_count: u64,
}
fn main() {
let mut user1 = User {
active: true,
email: String::from("someone@example.com"),
username: String::from("someusername123"),
sign_in_count: 1
};
let user2 = User {
email: String::from("another@example.com"),
..user1
};
println!("{:?}", user2);
}重要
使用 ..user1 时,user1 中的非 Copy 字段(如 String)会被移动到新实例,之后 user1.username 无法再用;bool 和 u64 这类实现了 Copy 的字段会被按值复制 如需保留原实例的所有字段,可在需要的字段上调用 clone