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>
是否需要对象安全
相关推荐
不吃香菜学java8 小时前
Redis的java客户端
java·开发语言·spring boot·redis·缓存
码事漫谈8 小时前
大模型输出的“隐性结构塌缩”问题及对策
前端·后端
小江的记录本9 小时前
【网络安全】《网络安全常见攻击与防御》(附:《六大攻击核心特性横向对比表》)
java·网络·人工智能·后端·python·安全·web安全
贵沫末9 小时前
python——打包自己的库并安装
开发语言·windows·python
文祐9 小时前
C++类之虚函数表及其内存布局(一个子类继承一个父类)
开发语言·c++
努力的小雨9 小时前
龙虾量化实战法(QClaw)
后端
zuowei28899 小时前
华为网络设备配置文件备份与恢复(上传、下载、导出,导入)
开发语言·华为·php
橙露10 小时前
SpringBoot 整合 MinIO:分布式文件存储上传下载
spring boot·分布式·后端
xiaohe0710 小时前
超详细 Python 爬虫指南
开发语言·爬虫·python
嗑嗑嗑瓜子的猫10 小时前
Java!它值得!
java·开发语言