跳至内容
张叶安的小站
用户工具
登录
站点工具
搜索
工具
显示页面
过去修订
反向链接
最近更改
媒体管理器
网站地图
登录
>
最近更改
媒体管理器
网站地图
您的足迹:
rust:第十三章trait
本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
====== 第十三章 Trait ====== ===== 13.1 什么是Trait ===== Trait定义了类型可以共享的行为。类似于其他语言中的接口(interface),但功能更强大。 **Trait的作用:** * 定义共享的行为 * 实现泛型编程 * 提供抽象接口 ===== 13.2 定义和实现Trait ===== ==== 定义Trait ==== <code rust> pub trait Summary { fn summarize(&self) -> String; } </code> ==== 实现Trait ==== <code rust> pub struct NewsArticle { pub headline: String, pub location: String, pub author: String, pub content: String, } impl Summary for NewsArticle { fn summarize(&self) -> String { format!("{}, by {} ({})", self.headline, self.author, self.location) } } pub struct Tweet { pub username: String, pub content: String, pub reply: bool, pub retweet: bool, } impl Summary for Tweet { fn summarize(&self) -> String { format!("{}: {}", self.username, self.content) } } </code> ==== 使用Trait ==== <code rust> let tweet = Tweet { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), reply: false, retweet: false, }; println!("1条新推文:{}", tweet.summarize()); </code> ===== 13.3 默认实现 ===== Trait可以提供默认实现: <code rust> pub trait Summary { fn summarize(&self) -> String { String::from("(Read more...)") } } impl Summary for NewsArticle {} // 使用默认实现 impl Summary for Tweet { fn summarize(&self) -> String { format!("{}: {}", self.username, self.content) } } </code> **默认实现可以调用其他方法:** <code rust> pub trait Summary { fn summarize_author(&self) -> String; fn summarize(&self) -> String { format!("(Read more from {}...)", self.summarize_author()) } } impl Summary for Tweet { fn summarize_author(&self) -> String { format!("@{}", self.username) } } </code> ===== 13.4 Trait作为参数 ===== ==== impl Trait语法 ==== <code rust> pub fn notify(item: impl Summary) { println!("突发新闻!{}", item.summarize()); } </code> ==== Trait Bound语法 ==== <code rust> pub fn notify<T: Summary>(item: T) { println!("突发新闻!{}", item.summarize()); } </code> **多个参数:** <code rust> // impl Trait pub fn notify(item1: impl Summary, item2: impl Summary) { // item1和item2可以是不同类型 } // Trait Bound(强制相同类型) pub fn notify<T: Summary>(item1: T, item2: T) { // item1和item2必须是相同类型 } </code> ===== 13.5 多个Trait Bound ==== ==== 使用+语法 ==== <code rust> use std::fmt::Display; pub fn notify(item: impl Summary + Display) { println!("突发新闻!{}", item.summarize()); } // 或使用where子句 pub fn notify<T>(item: T) where T: Summary + Display, { println!("突发新闻!{}", item.summarize()); } </code> ===== 13.6 返回实现Trait的类型 ==== <code rust> fn returns_summarizable() -> impl Summary { Tweet { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), reply: false, retweet: false, } } </code> **限制:** 只能返回单一具体类型 <code rust> // 错误!不能返回不同类型的impl Trait fn returns_summarizable(switch: bool) -> impl Summary { if switch { NewsArticle { headline: String::from("..."), location: String::from("..."), author: String::from("..."), content: String::from("..."), } } else { Tweet { username: String::from("..."), content: String::from("..."), reply: false, retweet: false, } } } </code> ===== 13.7 使用Trait Bound有条件地实现方法 ===== <code rust> use std::fmt::Display; struct Pair<T> { x: T, y: T, } impl<T> Pair<T> { fn new(x: T, y: T) -> Self { Self { x, y } } } impl<T: Display + PartialOrd> Pair<T> { fn cmp_display(&self) { if self.x >= self.y { println!("最大的成员是 x = {}", self.x); } else { println!("最大的成员是 y = {}", self.y); } } } </code> ===== 13.8 使用Trait Bound有条件地实现Trait ===== <code rust> use std::fmt::Display; struct Wrapper<T>(Vec<T>); impl<T: Display> Display for Wrapper<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[")?; for (i, v) in self.0.iter().enumerate() { if i > 0 { write!(f, ", ")?; } write!(f, "{}", v)?; } write!(f, "]") } } </code> **为任何实现了Display的类型实现ToString:** <code rust> impl<T: Display> ToString for T { // ... } </code> 这称为** blanket implementations**(全覆盖实现)。 ===== 13.9 常用标准库Trait ===== ==== Debug ==== <code rust> #[derive(Debug)] struct Point { x: i32, y: i32, } </code> ==== PartialEq和Eq ==== <code rust> #[derive(PartialEq, Eq)] struct Point { x: i32, y: i32, } </code> ==== PartialOrd和Ord ==== <code rust> #[derive(PartialEq, Eq, PartialOrd, Ord)] struct Point { x: i32, y: i32, } </code> ==== Clone和Copy ==== <code rust> #[derive(Clone, Copy)] struct Point { x: i32, y: i32, } </code> ==== Default ==== <code rust> #[derive(Default)] struct Config { debug: bool, timeout: u32, } let config = Config::default(); </code> ===== 13.10 完整示例:媒体播放器 ===== <code rust> // 定义Playable trait pub trait Playable { fn play(&self); fn pause(&self) { println!("Paused"); } fn stop(&self); } // 定义音频 pub struct Audio { title: String, artist: String, } impl Audio { pub fn new(title: &str, artist: &str) -> Self { Audio { title: title.to_string(), artist: artist.to_string(), } } } impl Playable for Audio { fn play(&self) { println!("Playing audio: {} by {}", self.title, self.artist); } fn stop(&self) { println!("Stopped audio: {}", self.title); } } // 定义视频 pub struct Video { title: String, resolution: (u32, u32), } impl Video { pub fn new(title: &str, width: u32, height: u32) -> Self { Video { title: title.to_string(), resolution: (width, height), } } } impl Playable for Video { fn play(&self) { println!("Playing video: {} at {}x{}", self.title, self.resolution.0, self.resolution.1); } fn pause(&self) { println!("Video paused at {}x{}", self.resolution.0, self.resolution.1); } fn stop(&self) { println!("Stopped video: {}", self.title); } } // 播放列表 pub struct Playlist { items: Vec<Box<dyn Playable>>, } impl Playlist { pub fn new() -> Self { Playlist { items: Vec::new() } } pub fn add(&mut self, item: Box<dyn Playable>) { self.items.push(item); } pub fn play_all(&self) { for item in &self.items { item.play(); } } } fn main() { let mut playlist = Playlist::new(); playlist.add(Box::new(Audio::new("Song", "Artist"))); playlist.add(Box::new(Video::new("Movie", 1920, 1080))); playlist.play_all(); } </code> ===== 练习题 ===== ==== 练习题13.1:实现Comparable trait ==== <code rust> trait Comparable { fn compare(&self, other: &Self) -> i32; } struct Rectangle { width: u32, height: u32, } impl Comparable for Rectangle { fn compare(&self, other: &Self) -> i32 { let area1 = self.width * self.height; let area2 = other.width * other.height; if area1 > area2 { 1 } else if area1 < area2 { -1 } else { 0 } } } fn main() { let r1 = Rectangle { width: 10, height: 20 }; let r2 = Rectangle { width: 5, height: 30 }; match r1.compare(&r2) { 1 => println!("r1更大"), -1 => println!("r2更大"), _ => println!("一样大"), } } </code> ==== 练习题13.2:实现Printable trait ==== <code rust> trait Printable { fn print(&self); } impl Printable for i32 { fn print(&self) { println!("整数:{}", self); } } impl Printable for String { fn print(&self) { println!("字符串:{}", self); } } impl<T: Printable> Printable for Vec<T> { fn print(&self) { println!("向量:["); for item in self { print!(" "); item.print(); } println!("]"); } } fn main() { let numbers = vec![1, 2, 3]; numbers.print(); } </code> ===== 本章小结 ===== 本章学习了Rust的Trait系统: * **定义Trait**:trait关键字定义共享行为 * **实现Trait**:impl Trait for Type * **默认实现**:提供默认方法体 * **Trait作为参数**:impl Trait或T: Trait * **Trait Bound**:约束泛型类型 * **条件实现**:基于Trait Bound实现方法和Trait Trait是Rust实现多态和代码复用的核心机制,理解Trait对于掌握Rust至关重要。
rust/第十三章trait.txt
· 最后更改:
2026/02/03 19:45
由
127.0.0.1
页面工具
显示页面
过去修订
反向链接
回到顶部