先看代码:

trait R{  // 定义: "跑" trait
    fn run(&self);  // 跑这个动作
}
//#[derive(Clone)] // 加上会编译错误
struct P{  
   list : Vec<Box<dyn R>> //可以跑的各种群体,里面可以同时有阿猫、阿狗,汽车、人等实现R的对象
}
impl P{
    pub fn run(&self){
        println!(" P 中 的对象开始跑.....\n");
        for r in &self.list{
            r.run();
        }
        println!(" P 中 的对象跑结束!\n");
    }
}

#[derive(Clone)] //可以加
struct Q<T> where T: R{
    list : Vec<Box<T>>  //只是能可以走的某一种单一对象群体,比如或是人,或是狗;不能人和狗混搭。
}
impl<T:R> Q<T> {
   pub fn run(&self){
       println!(" Q 中 的对象开始跑.....\n");
       for r in &self.list{
           r.run();
       }
       println!(" Q 中 的对象跑结束!\n");
   }

}

#[derive(Clone,Copy)] 
struct Man; //特地实现了Copy

impl R for Man{
    fn run(&self){
        println!("我是一位帅哥,配速是5分,能跑10km!");
    }
}
#[derive(Clone,Copy)]
struct Dog;//特地实现了Copy

impl R for Dog{
    fn run(&self){
        println!("我是一只中华田园狗狗,我跑起来很快,汪汪!");
    }
}

fn main(){
    let m = Man;
    let d = Dog;
    let two_kinds_runners = P{
        list: vec![Box::new(m),Box::new(d)],        
    };
    let two_same_runners = Q{
        list:vec![Box::new(m),Box::new(m)] //因为实现了Copy
    };
    two_kinds_runners.run();
    two_same_runners.run();
    
}

输出:

P 中 的对象开始跑…

我是一位帅哥,配速是5分,能跑10km!
我是一只中华田园狗狗,我跑起来很快,汪汪!

P 中 的对象跑结束!

Q 中 的对象开始跑…

我是一位帅哥,配速是5分,能跑10km!
我是一位帅哥,配速是5分,能跑10km!
Q 中 的对象跑结束!

在上面代码中,P和 Q有什么区别?
Vec<Box< dyn R>>: 是可以装实现R特性的不同trait对象【可以多态】.这个对象不一定实现了Clone.
Vec<Box< T>>: 是可以装实现R特性的某一种对象【只能单态】。这个对象必须是也实现了Clone.

需要说明的是,这两者有根本的区别。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐