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类型)。

猜你喜欢

转载自blog.csdn.net/weixin_39430411/article/details/121798655