多个实现块
本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 5 课,共 61 课。
Rust 允许你将结构体的方法拆分到多个 impl 块中。虽然所有内容都可以放在一个块中,但将它们分开能让代码更有条理、更易读。
下面是一个结构体,它的功能分散在两个实现块中:
struct BankAccount {
balance: f64,
}
// 构造函数和基本查询
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// 交易方法
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
这两个代码块配合得天衣无缝:Rust 会把它们当作一个整体。无论方法定义在哪个代码块中,你都可以调用它:
fn main() {
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
}
随着结构体变得越来越复杂,这种模式会特别有用。你可以把构造函数放在一起,将只读方法和会修改数据的方法分开,或者按功能组织。一个结构体可以有任意多个 impl 块。
挑战
简单创建一个 Player 结构体,包含两个字段:name(String)和 score(u32)。
将结构体的方法分布在两个单独的实现块中:
第一个 impl 块:构造函数和查询方法:
new:一个关联函数,接受name: String,并返回一个score设置为0的Playerget_score:接受&self,并以u32返回当前分数
第二个 impl 块:修改分数:
add_points:接受&mut self和points: u32,将这些分数加到当前分数上reset_score:接受&mut self,并将分数重置为0
你会收到 3 个输入:
- 第一行:玩家的名字(String)
- 第二行:第一轮要增加的分数(u32)
- 第三行:第二轮要增加的分数(u32)
使用 Player::new 创建一个玩家,增加第一轮的分数并打印分数,然后重置分数,增加第二轮的分数,并打印最终分数。
预期输出格式:
{score_after_first_round}
{score_after_reset_and_second_round}亲手试试
use std::io;
// TODO:定义 Player 结构体,包含 name(String)和 score(u32)字段
// TODO:第一个 impl 块,包含构造方法和查询方法(new、get_score)
// TODO:第二个 impl 块,包含修改分数的方法(add_points、reset_score)
fn main() {
let mut input = String::new();
// 读取玩家姓名
io::stdin().read_line(&mut input).expect("Failed to read line");
let name = input.trim().to_string();
// 读取第一轮得分
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let first_round: u32 = input.trim().parse().expect("Invalid number");
// 读取第二轮得分
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let second_round: u32 = input.trim().parse().expect("Invalid number");
// TODO:使用 Player::new 创建玩家
// TODO:加上第一轮得分并输出分数
// TODO:重置分数
// TODO:加上第二轮得分并输出最终分数
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Rust 在线编译器