泛型单态化没有运行时开销
enum Option {
Some(T),
None,
}
struct Point{
x:T,
y:T,
} //字段 x 和 y 都是 相同类型的
struct PointTU{
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{
x:T,
y:T,
} //字段 x 和 y 都是 相同类型的
impl Point{
fn get_x(&self)->&T{
return &self.x;
}
}
impl Point{
//计算点实例与坐标 (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 = Point{x:4, y:4};
let fl:Point = Point{x:2.0, y:2.0};
println!("{}, {}, {}, {}", int.x, fl.y, int.get_x(), fl.distiance_from_origin());
}
实例2:
struct Point{
x:T,
y:U,
}
impl Point{
fn mixup(self, other:Point)->Point{
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(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(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(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