Rust中的动态分发

动态分发在Rust中主要通过Trait对象实现,本质是一个胖指针:

  1. 数据指针:指向实际对象的内存地址
  2. 虚表指针

在Rust中,对于结构体和枚举类型而言,其字段的数据与impl块中实现的行为是分离的;而trait对象则无法添加数据,专门用于抽象某些共有行为。

trait对象可以被用在泛型或具体类型所处的位置,Rust类型系统会在编译期确保出现在相应位置上的值实现trait对象指定的trait

trait对象实现的动态数组结构体与带trait约束的泛型参数实现的结构体相异之处在于泛型参数一次只能被替代为一个具体的类型,trait对象则运行运行时填入多种不同的具体类型

差异 trait对象 泛型约束
编译机制 动态分发(运行时虚表查询) 静态分发(编译时单态化生成代码)
内存布局 胖指针存储(数据指针 + 虚表) 连续内存存储
安全要求 trait需要满足对象安全规则 无特殊要求
性能开销 虚表查询开销 无额外开销

使用trait对象与类型系统实现"鸭子类型",无需在运行时检查某个值是否实现了指定的方法或调用了未定义方法,Rust不允许此类代码通过编译。

确保trait对象满足对象安全规则,即trait中定义的方法满足以下2个条件:

  1. 方法的返回类型不是Self
  2. 方法中不含任何泛型参数

如何去思考命题:"trait对象必须是安全的" ?

  1. 什么情况下提出这个条件? 答:使用trait对象与类型系统通过动态分发实现"鸭子类型"
  2. 满足何种规则后trait对象是安全的?答:方法返回类型不是Self && 方法中不含任何泛型参数
  3. 假设规则存在不满足会导致什么后果?答:1.假设返回类型为Self,关键字Self为别名,指向实现当前trait或方法的具体类型,但trait对象需要运行时进行虚表查询以确认具体类型。2.假设方法中含有泛型参数,编译时无法确认内存大小
相关推荐
RobinDevNotes4 分钟前
Memvid 把 Agent 长期记忆塞进一个文件
人工智能·rust·openresty
愚农搬码9 分钟前
企业为什么需要表单引擎,而不是继续手写 Vue 表单?
后端
孟陬18 分钟前
技术周刊#158:ChatGPT 智能 UI 底层原理、个人智能体协议正式发布、一条 POST 请求即可锁死 Next.js 服务
人工智能·后端·全栈
小蒜学长33 分钟前
基于SpringBoot+Vue的云南地区扶贫助农系统的设计与实现(代码+数据库+LW)
java·vue.js·spring boot·后端·乡村振兴
码剑客37 分钟前
Gin+GORM+Redis 项目开发常见性能坑汇总(Go后端避坑指南)
redis·后端·golang·gin
java_nnnn1 小时前
Spring Boot 配置文件详解:从基础语法到 YAML 配置
spring boot·后端·github
SimonKing1 小时前
素笺( local-notes)全面优化,新增功能体验不一样的笔记
java·后端·程序员
何中应1 小时前
【Go-1】变量&常量定义
开发语言·后端·golang
愚农搬码1 小时前
电子表单、动态表单、表单设计器和表单引擎到底有什么区别?
java·后端
miofly1 小时前
GitHub 今日推荐|agent-desktop:通过无障碍树让 AI 代理直接操作桌面应用
rust·开源·github