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 Trait 或 Box<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>
是否需要对象安全 否 是
相关推荐
大鸡腿同学2 小时前
手心向上,手心向下
后端
程序猿追2 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓2 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播2 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
CCblandy3 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
墨云安全3 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php
摇滚侠3 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
Cc.Y4 小时前
Java零基础入门:深入Java核心:文件IO与序列化全解
java·开发语言·python
凤山老林5 小时前
Spring Boot 集成 Sa-Token 实现高可用权限认证:登录鉴权、动态路由权限与接口防重放实战
spring boot·后端·sa-token·bootstrap
jimy15 小时前
c++的 Type Traits (一)
开发语言·c++