• 恋爱脑学Rust之dyn关键字的作用


    在这里插入图片描述

    在 Rust 语言中,dyn 关键字允许我们在使用特征时创建“动态派发”——即通过一个统一的接口操作多种类型的具体实现。可以把它理解成一种“浪漫的妥协”:当我们不知道未来会爱上谁,只知道对方一定具有某种特征时,dyn 就像一个协议,让我们可以和“潜在的爱人们”沟通,而不需要具体知道他们的具体样子或独特的个性。

    想象一个浪漫的故事:小明认为爱很美好,但他不拘泥于具体的对象,只希望能找到任何一种和他有共同话题的人。他的标准是,对方只要能表现出特定的“特质”,比如温柔、幽默、冒险等就可以。但是小明并不能提前知道他会碰到的类型(他可能今天遇到温柔型的恋人,明天碰到幽默型的,或者还会遇到冒险型的)。dyn 在这里扮演的就是一个能让小明与多种类型的“恋人”交流的通用接口。

    而如果小明没有使用 dyn,他就必须清楚地知道恋人的具体类型和样貌,结果就是每次都只能选择一个固定的对象类型,失去了灵活性。让我们来看一个代码例子来帮助理解。

    dyn 的基本意图

    在 Rust 中,dyn 关键字的目的是提供一种让代码能够处理不同类型的对象,而不需要预先知道它们的具体类型的方式。通过 dyn 特征对象,小明可以通过单一接口和不同类型的“恋人”互动。以下例子中,我们模拟小明遇到不同类型恋人的场景。

    示例代码

    我们定义一个通用特征 Lover,每个实现 Lover 的类型都有自己表达爱的方式。我们可以选择使用 dyn Lover 或不使用 dyn Lover

    // 定义一个特征,描述不同类型的“恋人”
    trait Lover {
        fn express_love(&self);
    }
    
    // 定义几种具体的恋人类型
    struct Gentle;
    struct Adventurous;
    struct Funny;
    
    // 实现不同恋人的特征
    impl Lover for Gentle {
        fn express_love(&self) {
            println!("温柔型恋人:我会为你做一切,让你感到温暖");
        }
    }
    
    impl Lover for Adventurous {
        fn express_love(&self) {
            println!("冒险型恋人:我们去环游世界吧!");
        }
    }
    
    impl Lover for Funny {
        fn express_love(&self) {
            println!("幽默型恋人:我们一起大笑,过有趣的生活吧!");
        }
    }
    
    // 小明与恋人交流的函数
    fn love_story(lover: &dyn Lover) {
        lover.express_love();
    }
    

    使用 dyn 正确运行

    小明会在接下来的故事中遇到不同的恋人类型,这些类型各不相同,但是通过 dyn,小明可以使用相同的函数 love_story 和他们交流。

    fn main() {
        let gentle = Gentle;
        let adventurous = Adventurous;
        let funny = Funny;
    
        // 使用 dyn 特征对象
        love_story(&gentle);
        love_story(&adventurous);
        love_story(&funny);
    }
    

    运行结果:

    温柔型恋人:我会为你做一切,让你感到温暖
    冒险型恋人:我们去环游世界吧!
    幽默型恋人:我们一起大笑,过有趣的生活吧!
    

    小明成功与每种类型的恋人进行了互动,这就是 dyn 提供的动态派发功能,通过一个接口应对多种类型。

    如果不使用 dyn 会发生什么?

    如果小明尝试在没有使用 dyn 的情况下操作不同类型的恋人(例如,将恋人放在一个向量中),就会遇到编译错误,因为 Rust 无法确定在没有使用 dyn 的情况下如何存储不同类型的对象。

    fn main() {
        // Rust 会报错,因为 Vec 不知道如何存储多种不同的类型
        let lovers: Vec<&Lover> = vec![&Gentle, &Adventurous, &Funny];
    
        for lover in lovers {
            love_story(lover);
        }
    }
    

    错误信息:

    error[E0308]: mismatched types
       --> src/main.rs:5:32
        |
    5   |     let lovers: Vec<&Lover> = vec![&Gentle, &Adventurous, &Funny];
        |                                  ^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `Lover`, found struct `Gentle`
        |
        = note: expected reference `&Lover`
                   found reference `&Gentle`
    

    总结

    dyn 就像一个协议,允许小明(Rust 程序)和各种不同的对象(不同恋人类型)进行交流,而无需提前知道他们的具体类型。如果不使用 dyn,则程序需要对所有类型一一指定,缺乏灵活性,并且会导致编译错误。

  • 相关阅读:
    金仓数据库 KingbaseES PL/SQL 过程语言参考手册(8. PL/SQL动态SQL)
    [UVMC]UVM Connect基础教程
    A Simple, Fast and Effective Polygon Reduction Algorithm 代码 vscode编译过程
    数据的距离度量 一、欧式距离,曼哈顿距离,闵氏距离,切比雪夫距离,兰氏距离,马氏距离
    【Verilog】时序逻辑电路 -- 程序设计与应用
    c++问题
    EDID详解
    使用clip-path来画不同的形状,三角形,多边形,菱形,六边形等等
    macOS 使用 X11 运行远端 linux 中的 x11 client 图形程序
    Qt之语言家的简单使用(一)(Qt翻译UI,Qt Linguist的使用,含源码+注释)
  • 原文地址:https://blog.csdn.net/gzjimzhou/article/details/143438386