这是Rust基础系列的第7篇文章。结构体(Struct)允许你将多个相关联的值组合成一个自定义数据类型,用于在程序中对结构化概念建模。
定义与实例化结构体#
普通结构体包含具名字段:
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
fn main() {
let user1 = User {
active: true,
username: String::from("alice"),
email: String::from("alice@example.com"),
sign_in_count: 1,
};
println!("用户名:{}", user1.username);
}rust当字段名与作用域内的变量名一致时,可以使用简写语法:
fn build_user(email: String, username: String) -> User {
User {
active: true,
username,
email,
sign_in_count: 1,
}
}rust结构体更新语法#
使用 .. 语法可以基于已有实例快速创建新实例:
let user2 = User {
email: String::from("bob@example.com"),
..user1
};rust需要注意的是,具有移动语义的字段(如 user1 中的 username)将被移动到 user2 中。
元组结构体与单元结构体#
元组结构体没有字段名,通过位置索引访问:
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);rust单元结构体没有任何字段,常用于实现不需要保存状态的Trait:
struct AlwaysEqual;
let subject = AlwaysEqual;rust方法与impl块#
在 impl 块中为结构体定义方法。第一个参数通常是 &self(借用)、&mut self(修改)或 self(获取所有权):
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 square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!("面积:{}", rect1.area());
let sq = Rectangle::square(20);
println!("能否包含正方形?{}", rect1.can_hold(&sq));
}rust总结#
结构体使你能创建具有字段名称或元组位置的特定领域类型,而 impl 块则将行为与数据紧密结合。本系列的下一篇文章将探讨“枚举与模式匹配”。