当前位置:   article > 正文

Rust:泛型_rust 泛型结构体

rust 泛型结构体

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

1、泛型数据结构

枚举泛型

enum Option<T> {
    Some(T),
    None,
}
  • 1
  • 2
  • 3
  • 4

结构体泛型

泛型结构体定义

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

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

泛型结构体方法

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());
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

实例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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

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());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

在这里插入图片描述

默认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());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

在这里插入图片描述

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<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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

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);  //值的所有权
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

适用

pub fn notify(item1: impl Summary, item2: impl Summary) 
pub fn notify<T: Summary>(item1: T, item2: T) 
  • 1
  • 2

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

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());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

只适用于返回单一类型的情况。例如,这样就 不行:

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

参考:https://kaisery.github.io/trpl-zh-cn/ch09-01-unrecoverable-errors-with-panic.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/951253
推荐阅读
相关标签
  

闽ICP备14008679号