where 子句
本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 42 课,共 61 课。
添加更多 trait 约束后,函数签名可能会变得难以阅读。考虑一个包含多个泛型参数的函数,其中每个参数都需要实现多个 trait:
fn complex_operation<T: Display + Clone, U: Debug + Summary>(first: T, second: U) {
// ...
}
这样可行,但函数签名变得越来越拥挤。where 子句提供了一种更简洁的替代方式,可以将 trait 限定移到参数列表之后:
fn complex_operation<T, U>(first: T, second: U)
where
T: Display + Clone,
U: Debug + Summary,
{
// ...
}
这两个版本的功能完全相同:where 子句只是为了提高可读性。每种类型的要求都单独占一行,方便你快速查看每个泛型参数需要满足什么条件。
当约束复杂或泛型参数较多时,where 子句会特别有用。它能让函数名和参数一目了然,并将约束单独列在下方。当约束不止简单的 T: Trait 时,这是大多数 Rust 代码库首选的写法。
挑战
简单让我们构建一个数据处理系统,使用 where 子句让复杂的 trait 限定保持清晰易读!你将创建一个带有多个类型参数的泛型函数,每个参数都需要实现不同的 trait,并使用 where 语法整齐地组织这些限定。
你将在两个文件中组织代码:
processor.rs:定义两个公开的 trait,以及一个同时使用它们的泛型函数:Summarize:一个包含summary方法的 trait,该方法接收&self并返回StringValidate:一个包含validate方法的 trait,该方法接收&self并返回bool
process_items的公开泛型函数,接收两个不同泛型类型的参数。使用where子句指定第一个类型必须同时实现Clone和Summarize,第二个类型必须实现Validate。函数应打印第一个项目的摘要,然后打印第二个项目是否有效。main.rs:创建两个实现所需 trait 的公开结构体:Article:包含一个公开的title字段(String)。实现Summarize,使其返回Article: {title},并派生Clone。Form:包含一个公开的filled字段(bool)。实现Validate,使其返回filled的值。
process_items。
where 子句让函数签名比把所有限定都塞进尖括号中清晰得多。每种类型的要求都单独列出,方便你查看每个泛型参数需要满足什么条件。
输出应先显示摘要,然后显示验证结果:
Article: {title}
Valid: {true/false}例如,输入 Rust Tips 和 true 时:
Article: Rust Tips
Valid: true输入 Breaking News 和 false 时:
Article: Breaking News
Valid: false你将收到两个输入:文章标题,以及表单是否已填写(解析为 bool)。
亲手试试
mod processor;
use processor::{Summarize, Validate, process_items};
use std::io;
// TODO: 定义一个公开的结构体 Article,包含公开的 title 字段(String)
// 为 Article 派生 Clone
// TODO: 为 Article 实现 Summarize
// summary 方法应返回 "Article: {title}"
// TODO: 定义一个公开的结构体 Form,包含公开的 filled 字段(bool)
// TODO: 为 Form 实现 Validate
// validate 方法应返回 filled 的值
fn main() {
let mut title = String::new();
io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut filled_input = String::new();
io::stdin().read_line(&mut filled_input).expect("Failed to read line");
let filled: bool = filled_input.trim().parse().expect("Failed to parse bool");
// TODO: 使用给定的 title 创建一个 Article
// TODO: 使用给定的 filled 值创建一个 Form
// TODO: 将 article 和 form 传给 process_items
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Rust 在线编译器