Rust基础-关于trait之一

什么是trait?
答:告诉编译器类型具有哪些并且可以与其他类型共享的功能。

trait是干啥的?
答:为结构抽象定义一坨共享行为。并且定义约束,用以扩展(多态)。

trait的规则
1、该trait或类型是在本地crate里定义的
2、不能为外部类型实现外部的trait(一致性、孤儿原则)
3、trait可以有默认实现

上代码:

pub trait Draw {
    fn draw(&self)->String;
}
pub struct Sharp{
    pub components: Vec>,//任意实施了Draw的类型,未知
}
impl Sharp {
    pub fn run(&self) {
        for component in self.components.iter() {
            component.draw();  
        }
    }
}
pub struct Circle {
    pub name: String,
}

impl Draw for Circle {
    fn draw(&self)->String {
        println!("{} drawed",self.name);
        self.name.clone()
    }
}
pub struct Square {
    pub name: String,
}
impl Draw for Square {
    fn draw(&self)->String {
        println!("{} drawed",self.name);
        self.name.clone()
    }
}
fn draw_twice(sh: T) {
    sh.draw();           // Can call method because T: Shape
    sh.draw();
}

fn main() {
    let sharps = Sharp {
        components: vec![
            Box::new(Circle {
                name:"circle".to_string()
            }),
            Box::new(Square {
                name:"square".to_string()
            }),
        ],
    };
    sharps.run();
    let cir=Circle{name:"Circle".to_string()};
    draw_twice(cir);
}

输出:

Rust基础-关于trait之一_第1张图片

简单说一下

1、Man、Women、alien三个Struct结构不同,但都实现了Action这个trait。alien用了trait的默认方法。是不是有点像多态?是的就是多态。

2、为实现T:Action+ fmt::Debug这两个trait的结构(Women,Man)实现Daily trait,而alien不可以,这种方式叫blanket implementations。

3、Daily里还实现了to_string方法。是不是挺有趣的?

下面实现一个纯正的多态的例子

pub trait Draw {
    fn draw(&self)->String;
}
pub struct Sharp{
    pub components: Vec>,//任意实施了Draw的类型,未知
}
impl Sharp {
    pub fn run(&self) {
        for component in self.components.iter() {
            component.draw();  
        }
    }
}
pub struct Circle {
    pub name: String,
}

impl Draw for Circle {
    fn draw(&self)->String {
        println!("{} drawed",self.name);
        self.name.clone()
    }
}
pub struct Square {
    pub name: String,
}
impl Draw for Square {
    fn draw(&self)->String {
        println!("{} drawed",self.name);
        self.name.clone()
    }
}
fn main() {
    let sharps = Sharp {
        components: vec![
            Box::new(Circle {
                name:"circle".to_string()
            }),
            Box::new(Square {
                name:"square".to_string()
            }),
        ],
    };
    sharps.run();
}

输出:

这段代码里只要实现了trait:Draw的类型,就能被加入到Sharp里被调用。

相关文章:

Rust基础-关于trait之二_DarcyZ_SSM的博客-CSDN博客

 Rust基础-关于trait之三_DarcyZ_SSM的博客-CSDN博客

 Rust基础-关于trait之四-不得不说一下rust fat point_DarcyZ_SSM的博客-CSDN博客

 Rust基础-关于trait之五_DarcyZ_SSM的博客-CSDN博客

 Rust基础-关于trait之六,动态派发和静态派发的区别

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