Rust中enum_dispatch简单学习

Posted MateZero

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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类型)。

以上是关于Rust中enum_dispatch简单学习的主要内容,如果未能解决你的问题,请参考以下文章

Rust中enum_dispatch简单学习

一起来学rust|简单的mingrep

Rust学习--变量

rust学习笔记-变量和类型

rust学习笔记-变量和类型

Rust学习教程28 - 深入类型转换