Rust中enum_dispatch简单学习

在阅读别人的源码中,遇到了enum_dispatch这个Crate,那么他到底是做什么的呢?具体又怎么应用呢?在网上查找相应的资料后,大致搞清楚了它的用法 。现在我们就来学一下。

参考的文章为:https://crates.io/crates/enum_dispatch

该文章中介绍了:
enum_dispatch transforms your trait objects into concrete compound types, increasing their method call speed up to 10x.
也就抛弃原来的动态调用方法,改成自动实现,实现速度提升。

示例代码为:


///enum_dispatch transforms your trait objects into concrete compound types, increasing their method call speed up to 10x.
use enum_dispatch::enum_dispatch;

// trait enum pair one
#[enum_dispatch]
enum MyBehaviorEnum {
    MyImplementorA, //这里为实现了绑定tait的具体类型,而不是一个变量
    MyImplementorB, //这里为实现了绑定tait的具体类型,而不是一个变量
}

#[enum_dispatch(MyBehaviorEnum)]
trait MyBehavior {
    fn my_trait_method(&self);
}

// trait enum pair two
#[enum_dispatch]
trait MyBehavior2 {
    fn my_trait_method2(&self);
}

#[enum_dispatch(MyBehavior2)]
enum MyBehaviorEnum2 {
    MyImplementorA,
    MyImplementorB,
}

pub struct MyImplementorA {
    pub is_initialized: bool
}

impl MyImplementorA {
    fn new() -> Self {
        MyImplementorA{
            is_initialized:false,
        }
    }
}

impl MyBehavior for MyImplementorA {
    fn my_trait_method(&self) {
        println!("MyImplementorA::my_trait_method::is_initialized:{}",self.is_initialized);
    }
}

impl MyBehavior2 for MyImplementorA {
    fn my_trait_method2(&self) {
        println!("MyImplementorA::my_trait_method2::is_initialized:{}",self.is_initialized);
    }
}

pub struct MyImplementorB {
    pub is_initialized: bool
}

impl MyImplementorB {
    fn new() -> Self {
        MyImplementorB{
            is_initialized:true,
        }
    }
}

impl MyBehavior for MyImplementorB {
    fn my_trait_method(&self) {
        println!("MyImplementorB::my_trait_method::is_initialized:{}",self.is_initialized);
    }
}

impl MyBehavior2 for MyImplementorB {
    fn my_trait_method2(&self) {
        println!("MyImplementorB::my_trait_method2::is_initialized:{}",self.is_initialized);
    }
}

impl MyBehaviorEnum {
    fn show_info(&self) {
        match self {
            Self::MyImplementorA(a) => a.my_trait_method(),
            Self::MyImplementorB(b) => b.my_trait_method(),
        };
    }
}
impl MyBehaviorEnum2 {
    fn show_info2(&self) {
        match self {
            Self::MyImplementorA(a) => a.my_trait_method2(),
            Self::MyImplementorB(b) => b.my_trait_method2(),
        };
    }
}


fn main() {
    //测试一,注册枚举然后绑定特型,经过测试得知,具体实现可以自动转化为相应的枚举类型,并且枚举也可直接调用特型的函数,相当于实现了特型。
    let a: MyBehaviorEnum = MyImplementorA::new().into();
    let b: MyBehaviorEnum = MyImplementorB::new().into();
    a.my_trait_method();    //no dynamic dispatch
    b.my_trait_method();    //no dynamic dispatch

    //测试二,先注册特型再注册枚举,此时具体用法相同
    let c: MyBehaviorEnum2 = MyImplementorA::new().into();
    let d: MyBehaviorEnum2 = MyImplementorB::new().into();
    c.my_trait_method2();    //no dynamic dispatch
    d.my_trait_method2();    //no dynamic dispatch
    a.show_info();
    d.show_info2();
}

//output 
// MyImplementorA::my_trait_method::is_initialized:false
// MyImplementorB::my_trait_method::is_initialized:true
// MyImplementorA::my_trait_method2::is_initialized:false
// MyImplementorB::my_trait_method2::is_initialized:true
// MyImplementorA::my_trait_method::is_initialized:false
// MyImplementorB::my_trait_method2::is_initialized:true

enum_dispatch 其实是一个宏,使用它可以将枚举和对应的trait(特型)绑定在一起。与此同时,枚举的所有变量均为实现了该trait的类型。

这样 enum_dispatch 可以自动实现特型实现对象和枚举变量之间的转换。(其实本质是枚举变量绑定了一个同名类型的值,相当于一种语法糖)。

使用enum_dispatch其中一个的好处是我们只是的简单的增加枚举变量就行了(具体实现了trait类型)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AiMateZero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值