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<Box<dyn Draw>>,//任意实施了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<T: Draw>(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);
}

输出:

简单说一下

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<Box<dyn Draw>>,//任意实施了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之六,动态派发和静态派发的区别

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值