Rust語言學習筆記(6)
阿新 • • 發佈:2018-08-13
course lin key ati clas mem nsh lis The
Traits(特質)
// 特質 pub trait Summary { fn summarize(&self) -> String; } 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) } } // 使用特質 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 new tweet: {}", tweet.summarize()); // 缺省實現 pub trait Summary { fn summarize(&self) -> String { String::from("(Read more...)") } } // 使用特質的缺省實現 let article = NewsArticle { headline: String::from("Penguins win the Stanley Cup Championship!"), location: String::from("Pittsburgh, PA, USA"), author: String::from("Iceburgh"), content: String::from("The Pittsburgh Penguins once again are the best hockey team in the NHL."), }; println!("New article available! {}", article.summarize()); // 有缺省實現的方法可以調用沒有缺省實現的方法 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) } } 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 new tweet: {}", tweet.summarize()); // 作為參數類型的特質 pub fn notify(item: impl Summary) { println!("Breaking news! {}", item.summarize()); } pub fn notify<T: Summary>(item: T) { println!("Breaking news! {}", item.summarize()); } // 兩個特質類型的參數 pub fn notify(item1: impl Summary, item2: impl Summary) { pub fn notify<T: Summary>(item1: T, item2: T) { // 多個特質 fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U) -> i32 // where 子句 fn some_function<T, U>(t: T, u: U) -> i32 where T: Display + Clone, U: Clone + Debug { // 返回特質 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, } } // 根據特質選擇性地實現方法 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!("The largest member is x = {}", self.x); } else { println!("The largest member is y = {}", self.y); } } }
泛型
// 泛型函數 fn largest<T: PartialOrd + Copy>(list: &[T]) -> T { let mut largest = list[0]; for &item in list.iter() { if item > largest { largest = item; } } largest } let number_list = vec![34, 50, 25, 100, 65]; let result = largest(&number_list); println!("The largest number is {}", result); let char_list = vec!['y', 'm', 'a', 'q']; let result = largest(&char_list); println!("The largest char is {}", result); // 泛型結構 struct Point<T> { x: T, y: T, } let integer = Point { x: 5, y: 10 }; let float = Point { x: 1.0, y: 4.0 }; // 帶兩個類型參數的泛型結構 struct Point<T, U> { x: T, y: U, } let both_integer = Point { x: 5, y: 10 }; let both_float = Point { x: 1.0, y: 4.0 }; let integer_and_float = Point { x: 5, y: 4.0 }; // 標準庫中的泛型枚舉 enum Option<T> { Some(T), None, } enum Result<T, E> { Ok(T), Err(E), } // 泛型方法 struct Point<T> { x: T, y: T, } impl<T> Point<T> { fn x(&self) -> &T { &self.x } } let p = Point { x: 5, y: 10 }; println!("p.x = {}", p.x()); // 針對具體類型實現泛型結構的方法(==C++的全特化) impl Point<f32> { fn distance_from_origin(&self) -> f32 { (self.x.powi(2) + self.y.powi(2)).sqrt() } } // 帶類型參數的泛型方法 struct Point<T, U> { x: T, y: U, } impl<T, U> Point<T, U> { fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> { Point { x: self.x, y: other.y, } } } let p1 = Point { x: 5, y: 10.4 }; let p2 = Point { x: "Hello", y: 'c'}; let p3 = p1.mixup(p2); println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
Rust語言學習筆記(6)