rust中enum_dispatch简单学习(代码片段)

MateZero MateZero     2022-12-10     392

关键词:

在阅读别人的源码中,遇到了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学习笔记-变量和类型(代码片段)

...但rust的变量奇怪的地方是,变量不可变譬如这样一个简单到不能再简单的代码fnmain()leta=4;a=3;println!("",a)编译的时候就会报错3|a=3 查看详情

rust学习教程28-深入类型转换(代码片段)

...是类型安全的语言,因此在Rust中做类型转换不是一件简单的事,这一章节我们将对Rust中的类型转换进行详尽讲解。as转换先来看一段代码:fnmain()leta:i32=1 查看详情

rust机器学习的现状(代码片段)

...算、数学优化、系统和编译器工程等的组合。因此,为了简单起见,如果我们将ML划分 查看详情

rust学习教程33-hashmap(代码片段)

...t语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433KV存储HashMap和动态数组一样,HashMap也是Rust标准库中提供的集合类型,但是又与动态数组不同,HashMap中存储的是一一映射的KV键值对&... 查看详情

rust学习教程33-hashmap(代码片段)

...t语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433KV存储HashMap和动态数组一样,HashMap也是Rust标准库中提供的集合类型,但是又与动态数组不同,HashMap中存储的是一一映射的KV键值对&... 查看详情

rust学习-result/option/unwrap/?(代码片段)

学习Rust时,注意到有4个概念经常放到一起讨论:Result、Option、unwapr和?操作符。本文记录了我对这4个Rust概念的思考,这个思考过程帮助我理解并学会了如何写出更地道的Rust代码。1、Option-可空变量虽然Rust中有null的... 查看详情

rust学习教程32-动态数组vec(代码片段)

...ff0c;它的身影多次出现,我们一直没有细讲,只是简单的把它当作数组处理。动态数组允许你存储 查看详情

rust学习教程32-动态数组vec(代码片段)

...ff0c;它的身影多次出现,我们一直没有细讲,只是简单的把它当作数组处理。动态数组允许你存储 查看详情

rust学习教程18-数组(代码片段)

...#xff0c;我们的重点还是放在数组array上。数组的具体定义很简单:将多个类型相同的元素依次组合在一起,就是一个数组。结合上面的内容,可以得出数组的三要素:长度固定元素必须有相同的类型依次线性排列这... 查看详情

初窥门径:从helloworld开始rust学习

你好,我是鹿洺。从本文开始,我将和你一起学习rust。在开始之前,你需要完成rust工具链的安装。工欲善其事必先利其器,你可以使用任何编辑器来写rust代码,我比较喜欢VSCode,它免费,功强大而且速度很快。在VSCode下我安装... 查看详情

rust学习--变量(代码片段)

...每种编程语言都有变量的概念,我们可以把变量理解为最简单的存储方式,它是编码过程中是必不可少的。Rust的变量很有特色。变量不可变的特性让人想起了Erlang。以及后面的模式匹配,我觉得作者应该受Erlang影响很大。下面... 查看详情

用了这么多年rust终于搞明白了内存分布!(代码片段)

Rust作为一门学习曲线十分陡峭的语言,掌握其核心基础数据结构的内存分布对学习Rust会有很大的帮助,本文由浅入深仔细介绍了Rust的各个数据结构在内存中的分布情况。导读Rust作为一门学习曲线十分陡峭的语言,掌握其核心... 查看详情

rust学习教程28-深入类型转换(代码片段)

...是类型安全的语言,因此在Rust中做类型转换不是一件简单的事,这一章节我们将对Rust中的类型转换进行详尽讲解。as转换先来看一段代码:fnmain()leta:i32=10;letb:u16=100;ifa<bprintln!("Tenislessthanonehundred.");能跟... 查看详情

rust学习教程-引用与借用(代码片段)

...t语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433引用与借用上节中提到,如果仅仅是所有权转移,会让程序变得复杂,那能否像其它编程语言一样,使用某个变量的指针或者引... 查看详情

rust学习教程23-方法method(代码片段)

...t语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433方法Method从面向对象语言过来的同学对于方法肯定不陌生,class里面就充斥着方法的概念,在Rust中方法的概念也大差不差,往往和对... 查看详情

rust学习教程23-方法method(代码片段)

...t语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433方法Method从面向对象语言过来的同学对于方法肯定不陌生,class里面就充斥着方法的概念,在Rust中方法的概念也大差不差,往往和对... 查看详情

rust学习教程22-全模式列表(代码片段)

...t语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433全模式列表在本书中我们已领略过许多不同类型模式的例子.本节的目标就是把这些模式语法都罗列出来,方便大家检索查阅。匹配字面值let... 查看详情

rust学习教程22-全模式列表(代码片段)

...t语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433全模式列表在本书中我们已领略过许多不同类型模式的例子.本节的目标就是把这些模式语法都罗列出来,方便大家检索查阅。匹配字面值let... 查看详情