Rust速记:泛型,特征,动态派发

泛型:

#[derive(Debug)]
struct Point {
    x: T1,
    y: T2,
}

impl Point {
    fn x(&self) -> &T1 {
        &self.x
    }
}

impl Point {
    fn mixup(self, rhs: Point) -> Point {
        Point { x: self.x, y: rhs.y}
    }
}

fn main() {
    let p1: Point = Point{x:12, y:4};
    let p2: Point = Point{x:3, y:4.5};
    let p3: Point = Point{x:23, y:'B'};

    print!("{:?}", p1.mixup(p3));
}

特征:


#[derive(Debug, Clone)]
pub struct NewsArticle {
   pub author: String,
   pub headling: String,
   pub content: String,
}
#[derive(Debug, Clone)]
pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}

pub trait Summary {
    //NO default method
    fn summarize(&self) -> String;
    //have default method
    fn author(&self) -> String {
        "Unknow".to_owned()
    }
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}: {}", self.author, self.headling)
    }
    fn author(&self) -> String {
        self.author.to_owned()
    }
}

impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("{}: {}", self.username, self.content)
    }
    fn author(&self) -> String {
        self.username.to_owned()
    }
}

pub fn extra(news: T)
    where T:Summary,
{
    println!("Extra! {}", news.summarize());
}


pub trait Brief {
    fn brief_news(&self) -> String;
}

impl Brief for T 
    where T: Summary,
{
    fn brief_news(&self) -> String {
        format!("{}..", (self.summarize())[0..=15].to_owned())
    }
}

fn main() {
    let news = NewsArticle{
        author: "John Doe".to_owned(),
        headling: "happy new year".to_owned(),
        content: "Today is new year".to_owned(),
    };

    let my_tweet = Tweet{
        username: "FishRune".to_owned(),
        content: "my cat like sleep on my laptop".to_owned(),
        reply: false,
        retweet: false,
    };

    extra(my_tweet.clone());
    println!("{}", my_tweet.brief_news());
}

动态派发:


pub trait Draw {
    fn draw(&self);
}

pub struct Screen{
    pub components: Vec>,
}

pub struct  Button {
    width: i32,
    height: i32,
    icon: Option,
}

pub struct  Widget {
    width: i32,
    height: i32,
    backgound_color: (i32, i32, i32),
}

impl Draw for Button {
    fn draw(&self) {
        /*do something...*/
    }
}

impl Draw for Widget  {
    fn draw(&self) {
        /*do something...*/
    }
}

fn main() {
    let button = Button {
        width: 80,
        height: 80,
        icon: Some("../pic/XXX.png".to_owned()),
    };
    let widget = Widget {
        width: 400,
        height: 200,
        backgound_color: (122, 20, 0),
    };

    let screen = Screen {
        components: vec![Box::new(button), Box::new(widget)],
    };
}

特征对象和动态派发:

特征对象语法简介,运行开销更少,但是编译文件更大,与之相反动态派发则是在运行时建立虚表(与C++虚函数一样)。

另一个关键的不同在于动态派发的容器可以储存多种拥有同一特征的类,而特征对象则受限于某一类,如上面代码所示,screen的vec可以拥有button和widget两种类。

动态派发的另一个使用场景是当函数返回一个闭包,并且返回的闭包内容随情况而定时

fn return_closure(a: i32) -> Box i32> {
    if a > 0 {
        Box::new(move |b: i32| a+b)
    }else {
        Box::new(move |b: i32| a-b)
    }
}

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