WHAT - Rust 静态派发(Static Dispatch)和 动态派发(Dynamic Dispatch)

文章目录

  • [静态派发(Static Dispatch)](#静态派发(Static Dispatch))
  • [动态派发(Dynamic Dispatch)](#动态派发(Dynamic Dispatch))
  • 总结对比

在 Rust 中,静态派发(Static Dispatch)动态派发(Dynamic Dispatch) 是 trait 调用的两种主要方式,涉及到 trait 的使用方式和性能之间的权衡。

下面是两者的详细对比:

静态派发(Static Dispatch)

  • 定义 :在编译期就确定具体调用哪个方法,生成对应的代码(单态化 monomorphization)。

  • 实现方式 :使用 泛型(generics) 实现的 trait 调用。

  • 优点

    • 编译期确定类型 → 性能更好(没有运行时开销)。
    • 编译器可以进行更多优化(比如内联)。
  • 缺点

    • 每个泛型参数实例都会生成一份代码,可能会增加最终可执行文件大小(code bloat)。

示例:

rust 复制代码
trait Speak {
    fn speak(&self);
}

struct Dog;
struct Cat;

impl Speak for Dog {
    fn speak(&self) {
        println!("Woof!");
    }
}

impl Speak for Cat {
    fn speak(&self) {
        println!("Meow!");
    }
}

// 使用泛型参数 T(静态派发)
fn animal_speak<T: Speak>(animal: T) {
    animal.speak();
}

动态派发(Dynamic Dispatch)

  • 定义:在运行时通过虚表(vtable)来决定调用哪个方法。

  • 实现方式 :使用 trait 对象(如 &dyn TraitBox<dyn Trait>

  • 优点

    • 类型擦除后,可以写出更灵活的代码。
    • 适合在类型不确定或需要异构集合时使用。
  • 缺点

    • 有运行时开销(指针跳转 + vtable)。
    • trait 需要是对象安全(object-safe)。

示例:

rust 复制代码
fn animal_speak(animal: &dyn Speak) {
    animal.speak();  // 动态派发,通过 vtable 调用方法
}

总结对比

特性 静态派发 动态派发
调用时机 编译时 运行时
性能 高(无额外开销) 相对较低(有 vtable 指针开销)
代码大小 可能更大(每种类型生成一份代码) 更小(共享 trait 对象)
使用方式 泛型 T: Trait &dyn Trait, Box<dyn Trait>
是否需要对象安全
相关推荐
ClouGence20 分钟前
SAP HANA 到 Doris 数据迁移:4 种方案对比与迁移教程
数据库·后端·dba
LVZ23 分钟前
用了半年 AI 写代码,最烦的不是代码,是环境
前端·后端·开源
格林威28 分钟前
工业相机Chunk功能全解析:图像嵌入时间戳、编码器元数据(附堡盟C#代码)
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
云边有个稻草人30 分钟前
从一条危险的 WHERE 条件说起:金仓数据库逻辑安全警示
后端
用户77139702070630 分钟前
从一脸懵到熟练使用:我的C#CAD二次开发日常中那些“反人类“的循环技巧
后端
小大宇1 小时前
Python 集成 Conda
开发语言·python·conda
JaneConan1 小时前
鸿蒙报错速查:arkts-no-any any 类型禁用,用了就炸,根因 + 真解法
后端·harmonyos
还是奇怪1 小时前
Simon Willison 用 DSPy 优化 Datasette Agent 提示词:提示工程正在变成可测试的软件工程
java·开发语言·软件工程
颜酱2 小时前
# 02 | 搭骨架:用 LangGraph 编排 12 步工作流(思路)
前端·人工智能·后端
颜酱2 小时前
02 | 搭骨架:用 LangGraph 编排 12 步工作流
前端·人工智能·后端