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

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

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

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

dyn 的基本意图

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

示例代码

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

rust 复制代码
// 定义一个特征,描述不同类型的"恋人"
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 和他们交流。

rust 复制代码
fn main() {
    let gentle = Gentle;
    let adventurous = Adventurous;
    let funny = Funny;

    // 使用 dyn 特征对象
    love_story(&gentle);
    love_story(&adventurous);
    love_story(&funny);
}

运行结果:

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

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

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

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

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

    for lover in lovers {
        love_story(lover);
    }
}

错误信息:

plaintext 复制代码
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,则程序需要对所有类型一一指定,缺乏灵活性,并且会导致编译错误。

相关推荐
独好紫罗兰6 小时前
通过例子学 rust 个人精简版 5-all
rust
heroboyluck6 小时前
rust 实例化动态对象
开发语言·rust·trait
Source.Liu6 小时前
【CXX】4 跨平台构建系统特性对比
c++·rust·cxx
Hello.Reader6 小时前
深入探讨 Rust 中的 Deref Trait:让智能指针像常规引用一样工作
开发语言·后端·rust
yoona10209 小时前
Rust编程语言入门教程 (七)函数与控制流
开发语言·rust·区块链·学习方法
JD技术委员会11 小时前
Rust 未来会成为主流的编程语言吗?
开发语言·后端·rust
无名之逆11 小时前
探索 Hyperlane:高性能 Rust Web 框架的崛起
java·开发语言·后端·python·算法·面试·rust
懒羊羊我小弟1 天前
Webpack 基础入门
前端·webpack·rust·node.js·es6
武侠编程2 天前
Rust兵器谱|流星镖:tokio
rust
大雄野比2 天前
rust学习三、基本类型
开发语言·学习·rust