赞
踩
泛型单态化没有运行时开销
enum Option<T> {
Some(T),
None,
}
struct Point<T>{ x:T, y:T, } //字段 x 和 y 都是 相同类型的 struct PointTU<T, U>{ x:T, y:U, } //字段 x 和 y 可以有不同类型 fn main() { let int = Point{x:4, y:4}; let fl = Point{x:4.4, y:5.4}; println!("{}, {}", int.x, fl.y); let hun = PointTU{x:"44", y:4.5}; println!("{}, {}", hun.x, hun.y); }
struct Point<T>{ x:T, y:T, } //字段 x 和 y 都是 相同类型的 impl <T> Point<T>{ fn get_x(&self)->&T{ return &self.x; } } impl Point<f32>{ //计算点实例与坐标 (0.0, 0.0) 之间的距离,并使用了只能用于浮点型的数学运算符。 fn distiance_from_origin(&self)->f32{ return (self.x.powi(2) + self.y.powi(2)).sqrt(); } } fn main() { let int:Point<i32> = Point{x:4, y:4}; let fl:Point<f32> = Point{x:2.0, y:2.0}; println!("{}, {}, {}, {}", int.x, fl.y, int.get_x(), fl.distiance_from_origin()); }
实例2:
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, } } } fn main() { let p1 = Point{x:5, y:10.4}; let p2 = Point{x:"hello", y:'C'}; let p3 = p2.mixup(p1); println!("{:?}, {}", p3.x, p3.y) }
trait用来实现多态。类似C++中的接口
pub trait Summary{ fn summarize(&self)->String; } pub struct NewsArticle{ pub headline:String, pub location:String, pub author:String, pub content:String, } pub struct Tweet{ pub username:String, pub content:String, pub reply:bool, pub retweet:bool, } impl Summary for NewsArticle{ fn summarize(&self)->String{ format!("{}, by {} ({})", self.headline, self.author, self.location) } } impl Summary for Tweet { fn summarize(&self) -> String { return format!("{}: {}", self.username, self.content); } } fn main() { let tweet = Tweet{ username:String::from("horse_ebooks"), content:String::from("I have nothing"), reply:false, retweet:false, }; println!("{}", tweet.summarize()); let article = NewsArticle { headline: String::from("NewsArticle_headline"), 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!("{}", article.summarize()); }
默认指定行为
pub trait Summary{ fn summarize(&self)->String{ return String::from("默认实现"); } } pub struct NewsArticle{ pub headline:String, pub location:String, pub author:String, pub content:String, } pub struct Tweet{ pub username:String, pub content:String, pub reply:bool, pub retweet:bool, } impl Summary for NewsArticle{ //必须写 //因为没有实现summarize所以会调用默认实现的trait } impl Summary for Tweet { fn summarize(&self) -> String { return format!("{}: {}", self.username, self.content); } } fn main() { let tweet = Tweet{ username:String::from("horse_ebooks"), content:String::from("I have nothing"), reply:false, retweet:false, }; let article = NewsArticle { headline: String::from("NewsArticle_headline"), 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!("{}", tweet.summarize()); println!("{}", article.summarize()); }
pub trait Summary{ fn ari_authon(&self)->String; fn summarize(&self)->String{ return String::from("默认实现"); } } pub struct NewsArticle{ pub headline:String, pub location:String, pub author:String, pub content:String, } pub struct Tweet{ pub username:String, pub content:String, pub reply:bool, pub retweet:bool, } impl Summary for NewsArticle{ //must fn ari_authon(&self)->String{ return format!("{}", self.author); } } pub fn notify_bound<T:Summary>(item:T){ println!("参数:{}", item.ari_authon()) } fn main() { let article = NewsArticle { headline: String::from("NewsArticle_headline"), 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!("{}, {}", article.summarize(), article.ari_authon()); notify_bound(article) }
trait bound语法糖
pub trait Summary{ fn ari_authon(&self)->String; fn summarize(&self)->String{ return String::from("默认实现"); } } pub struct NewsArticle{ pub headline:String, pub location:String, pub author:String, pub content:String, } pub struct Tweet{ pub username:String, pub content:String, pub reply:bool, pub retweet:bool, } impl Summary for NewsArticle{ //must fn ari_authon(&self)->String{ return format!("{}", self.author); } } pub fn notify(item:impl Summary){ //在 notify 函数体中,可以调用任何来自 Summary trait 的方法 println!("参数:{}", item.summarize()) } fn main() { let article = NewsArticle { headline: String::from("NewsArticle_headline"), 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!("{}, {}", article.summarize(), article.ari_authon()); notify(article); //值的所有权 }
适用
pub fn notify(item1: impl Summary, item2: impl Summary)
pub fn notify<T: Summary>(item1: T, item2: T)
trait bound实现PartialOrd trait和 Copy trait:
//为了只对实现了 Copy 的类型调用这些代码,可以在 T 的 trait bounds 中增加 Copy:error[E0508]: cannot move out of type `[T]`, a non-copy slice fn largest<T:PartialOrd + Copy>(list:&[T])->T{ //PartialOrd trait (允许比较),or:error[E0369]: binary operation `>` cannot be applied to type `T` let mut largest = list[0]; //i32 和 char 这样的类型是已知大小的并可以储存在栈上,所以他们实现了 Copy trait //largest 函数改成使用泛型后,现在 list 参数的类型就有可能是没有实现 Copy trait 的。 //可能不能将 list[0] 的值移动到 largest 变量中 //只要传递给 largest 的 slice 值的类型实现了 PartialOrd 和 Copy 这两个 trait for &item in list.iter(){ if item > largest{ largest = item; } } largest } fn main() { let number_list = vec![34, 50, 25, 100, 65]; let result = largest(&number_list); println!("{}", result); let char_list = vec!['y', 'm', 'a', 'q']; let result = largest(&char_list); println!("The largest char is {}", result); }
pub trait Summary{ fn ari_authon(&self)->String; fn summarize(&self)->String{ return String::from("默认实现"); } } pub struct NewsArticle{ pub headline:String, pub location:String, pub author:String, pub content:String, } impl Summary for NewsArticle{ //must fn ari_authon(&self)->String{ return format!("{}", self.author); } } fn returns_summarizable() -> impl Summary { NewsArticle { headline: String::from("NewsArticle_headline"), 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."), } } fn main() { let al = returns_summarizable(); println!("{}, {}", al.summarize(), al.ari_authon()); }
只适用于返回单一类型的情况。例如,这样就 不行:
fn returns_summarizable(switch: bool) -> impl Summary { if switch { 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."), } } else { Tweet { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), reply: false, retweet: false, } } }
参考:https://kaisery.github.io/trpl-zh-cn/ch09-01-unrecoverable-errors-with-panic.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。