结构体(Struct)
学习目标
- 定义和实例化结构体
- 掌握方法(impl)定义
- 理解关联函数
- 掌握元组结构体和单元结构体
核心概念
定义结构体
struct User {
username: String,
email: String,
age: u32,
active: bool,
}
fn main() {
let user = User {
username: String::from("rustacean"),
email: String::from("rust@example.com"),
age: 25,
active: true,
};
println!("{} 的邮箱是 {}", user.username, user.email);
}
可变结构体
fn main() {
let mut user = User {
username: String::from("alice"),
email: String::from("alice@example.com"),
age: 30,
active: true,
};
user.email = String::from("new@example.com");
}
结构体更新语法
fn main() {
let user1 = User {
username: String::from("alice"),
email: String::from("alice@example.com"),
age: 30,
active: true,
};
let user2 = User {
username: String::from("bob"),
email: String::from("bob@example.com"),
..user1
};
}
方法(impl)
struct Rectangle {
width: f64,
height: f64,
}
impl Rectangle {
fn area(&self) -> f64 {
self.width * self.height
}
fn perimeter(&self) -> f64 {
2.0 * (self.width + self.height)
}
fn scale(&mut self, factor: f64) {
self.width *= factor;
self.height *= factor;
}
fn into_square(self) -> Rectangle {
let side = self.width.max(self.height);
Rectangle { width: side, height: side }
}
}
fn main() {
let mut rect = Rectangle { width: 10.0, height: 5.0 };
println!("面积: {}", rect.area());
println!("周长: {}", rect.perimeter());
rect.scale(2.0);
println!("放大后面积: {}", rect.area());
}
关联函数(不带 self)
impl Rectangle {
fn new(width: f64, height: f64) -> Self {
Rectangle { width, height }
}
fn square(size: f64) -> Self {
Rectangle { width: size, height: size }
}
}
fn main() {
let rect = Rectangle::new(10.0, 5.0);
let sq = Rectangle::square(7.0);
}
元组结构体
struct Color(u8, u8, u8);
struct Point(f64, f64, f64);
fn main() {
let red = Color(255, 0, 0);
let origin = Point(0.0, 0.0, 0.0);
println!("R={}, G={}, B={}", red.0, red.1, red.2);
}
单元结构体
struct Marker;
impl Marker {
fn mark(&self) {
println!("marked!");
}
}
Debug 和 Display
#[derive(Debug)]
struct Point {
x: f64,
y: f64,
}
fn main() {
let p = Point { x: 1.0, y: 2.0 };
println!("{:?}", p);
println!("{:#?}", p);
}
实践练习
练习 1:学生管理
#[derive(Debug)]
struct Student {
name: String,
grade: u32,
scores: Vec<f64>,
}
impl Student {
fn new(name: &str, grade: u32) -> Self {
Student {
name: String::from(name),
grade,
scores: Vec::new(),
}
}
fn add_score(&mut self, score: f64) {
self.scores.push(score);
}
fn average(&self) -> f64 {
if self.scores.is_empty() {
return 0.0;
}
self.scores.iter().sum::<f64>() / self.scores.len() as f64
}
}
fn main() {
let mut alice = Student::new("Alice", 3);
alice.add_score(95.0);
alice.add_score(87.0);
alice.add_score(92.0);
println!("{:?}, 平均分: {:.1}", alice, alice.average());
}
练习 2:链表节点
#[derive(Debug)]
struct Node {
value: i32,
next: Option<Box<Node>>,
}
impl Node {
fn new(value: i32) -> Self {
Node { value, next: None }
}
fn push(&mut self, value: i32) {
match &mut self.next {
Some(node) => node.push(value),
None => self.next = Some(Box::new(Node::new(value))),
}
}
fn to_vec(&self) -> Vec<i32> {
let mut result = vec![self.value];
if let Some(next) = &self.next {
result.extend(next.to_vec());
}
result
}
}
fn main() {
let mut head = Node::new(1);
head.push(2);
head.push(3);
println!("{:?}", head.to_vec());
}
常见错误
1. 忘记字段
let user = User {
username: String::from("alice"),
email: String::from("alice@example.com"),
};
2. 可变性
3. 生命周期
struct Excerpt {
text: &str,
}
struct Excerpt<'a> {
text: &'a str,
}
小结
| 概念 | 语法 |
|---|
| 定义 | struct Name { field: Type } |
| 实例化 | Name { field: value } |
| 方法 | impl Name { fn method(&self) {} } |
| 关联函数 | impl Name { fn new() -> Self {} } |
| 更新语法 | ..other |
| Debug | #[derive(Debug)] |