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>
是否需要对象安全
相关推荐
Layflok5 分钟前
《黑马笔记》 --- C++ 提高编程
开发语言·c++·stl
陈随易11 分钟前
国产之光,把AI融入到语言级别的编程语言-MoonBit
前端·后端·程序员
我来整一篇23 分钟前
ASP.NET Core中使用NLog和注解实现日志记录
后端·asp.net
上单带刀不带妹25 分钟前
ES6中import与export的用法详解
开发语言·javascript·es6·import·export
工程师00730 分钟前
C#接口的定义与使用
开发语言·c#·接口
sali-tec30 分钟前
C# 基于halcon的视觉工作流-章27-带色中线
开发语言·人工智能·算法·计算机视觉·c#
小青年46937 分钟前
springboot3 vue3校园失物招领系统实战开发教程
后端
天天摸鱼的java工程师41 分钟前
如何实现一个分布式锁?——来自 Java 老兵的实战总结 🚀🔐
java·后端·面试
_杨瀚博1 小时前
MAVEN构建分离依赖JAR
后端
zero_face1 小时前
记录一次Spring5中事件通知机制bug引起的生产事故
后端·spring·debug