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>
是否需要对象安全
相关推荐
90后的晨仔2 分钟前
阿里云服务器如何给子账号设置指定具体的那一台服务器?
后端
期待のcode22 分钟前
springboot热部署
java·spring boot·后端
expect7g24 分钟前
Paimon源码解读 -- FULL_COMPACTION_DELTA_COMMITS
大数据·后端·flink
踏浪无痕34 分钟前
周末拆解:QLExpress 如何做到不编译就能执行?
后端·算法·架构
222you37 分钟前
Spring框架的介绍和IoC入门
java·后端·spring
毕设源码-朱学姐37 分钟前
【开题答辩全过程】以 基于Java的人体骨骼健康知识普及系统为例,包含答辩的问题和答案
java·开发语言
lly20240641 分钟前
Julia 函数
开发语言
sheji341644 分钟前
【开题答辩全过程】以 基于JAVA的社团管理系统为例,包含答辩的问题和答案
java·开发语言
用户6151265617331 小时前
Java生态新纪元:虚拟线程、模式匹配与未来的编程范式
后端
风雨同舟的代码笔记1 小时前
Java并发编程基石:深入解析AQS原理与应用实战
后端