Rust学习(19):泛型【不太理解。。。】

泛型单态化没有运行时开销

文章目录

  • 1、泛型数据结构
    • 枚举泛型
    • 结构体泛型
      • 泛型结构体定义
      • 泛型结构体方法
  • 2、trait
    • 什么是trait
    • 默认trait
    • trait作为参数
    • trait作为返回值

1、泛型数据结构

枚举泛型

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)
}

2、trait

什么是trait

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());
}

在这里插入图片描述

默认trait

默认指定行为

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());
}

在这里插入图片描述

trait作为参数

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);
}

trait作为返回值

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

你可能感兴趣的:(#,rust)