Rust impl Trait和dyn Trait

impl Trait:静态分发
dyn Trait:动态分发

静态分发:在编译期就确定了具体返回类型,函数只能返回一种类型。
动态分发:在运行时才能确定具体返回类型,函数可以返回多种类型。

Trait Object:指向trait的指针,假设Animal是一个triait,那么&Animal和Box<Animal>都是一种Trait Object。

胖指针:用于指代动态大小类型(DST)的引用和原始指针(切片或特征对象)。胖指针包含一个指针以及一些使DST完成(例如长度)的信息。

返回值为impl Trait时用dyn Trait是没问题的

示例代码:

trait Animal {
    fn get_kind(&self) -> String;

    fn default_impl(&self) {
        println!("default impl");
    }
}

impl dyn Animal {
    fn trait_object() {
        println!("trait object");
    }
}

#[derive(Debug)]
struct Dog {}

impl Animal for Dog {
    fn get_kind(&self) -> String {
        "Dog".to_string()
    }
}

struct Cat {}

impl Animal for Cat {
    fn get_kind(&self) -> String {
        "Cat".to_string()
    }
}

// 静态分发
fn get_animal_static() -> impl Animal {
    let x = 1;
    if x == 1 {
        Dog {}
    } else {
        Dog {}
    }
}

// 动态分发
fn get_animal_dyn() -> Box<dyn Animal> {
    let x = 0;
    if x == 1 {
        Box::new(Dog {})
    } else {
        Box::new(Cat {})
    }
}

fn main() {
    let dog = Dog {};
    dog.default_impl();

    let cat = Cat {};
    cat.default_impl();

    // 只有 trait objects 才能调用
    // dog.trait_object();
    // cat.trait_object();

    <dyn Animal>::trait_object();
    let _ = &<dyn Animal>::trait_object();

    let animal = get_animal_static();
    // Dog
    println!("{}", animal.get_kind());

    let animal = get_animal_dyn();
    // Cat
    println!("{}", animal.get_kind());
}

参考:
胖指针:
https://www.sohu.com/a/475756949_121124378

impl Trait & dyn Trait
https://zhuanlan.zhihu.com/p/23791817
https://zhuanlan.zhihu.com/p/109990547

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值