当前位置:网站首页>rust中的静态分发和动态分发
rust中的静态分发和动态分发
2022-07-23 15:05:00 【pilaf1990】
rust中的范型属于静多态,它是编译时多态,无运行时性能损耗。在编译时,不论是范型枚举、范型函数还有范型结构体,都会被单态化(Monomorphization)。
以下面的范型函数为例:
fn main() {
let foo = Foo;
static_dispatch(&foo);
dynamic_dispatch(&foo);
}
#[derive(Debug)]
struct Foo;
trait Bar {
fn baz(&self);
}
impl Bar for Foo {
fn baz(&self) {
println!("{:?}", self);
}
}
// 静态分发
fn static_dispatch<T>(t: &T) where T: Bar {
t.baz();
}
// 动态分发
fn dynamic_dispatch(t: &dyn Bar) {
t.baz();
}
static_dispatch范型函数在编译的时候,会找到Bar trait的所有实现,并为它们分别生成一个实现,比如上面的示例中,只有Foo一个结构体实现了Bar trait,那么其实在编译期static_dispatch会生成
fn static_dispatch(t: &Foo){
t.baz();
}
这个方法,如果还有其它的Bar trait实现还会生成它对应的具体方法。即在编译的时候就会将每个Bar trait的实现都生成一个具体方法,运行的时候就无开销了。
将上述方法放到https://play.rust-lang.org/上选择ASM:
可以看到生成的编译后的代码中确实是单态化了的:
而dynamic_dispatch的方法入参是t:&dyn Bar,是一种动态分发。参数t标注的类型&Bar是trait对象。trait本身也是一种抽象而非具体的类型,但它的类型大小在编译期是无法确定的,所以trait对象必须使用胖指针。可以利用引用操作符&或Box<T>来制造一个trait对象。trait对象等价于下面的结构体:
pub struct TraitObject{
pub data: *mut(),
pub vtable: *mut(),
}
TraitObject包括两个指针:data指针和vtable指针。以impl MyTrait for T为例,data指针指向trait对象保存的类型数据T,vtable指针指向包含为T实现的MyTrait的vtable(virtual table,该名称来源于C++,所以可以称之为虚表)。虚表的本质是一个结构体,包含了析构函数,大小,对齐和方法等信息。
在编译期,编译器只知道TraitObject包含指针的信息,并且指针的大小也是确定的(因为要在栈上分配,大小必须得是确定的),但是并不知道要调用哪个方法。在程序运行期间,当有trait_object.method()方法被调用时,TraitObject会根据虚表指针从虚表中查找出正确的函数指针,然后再进行动态调用(Java的运行时多态也是类似的)。这也是将trait对象成为动态分发的原因。
参考资料:
1.《Rust编程之道》(张汉东著P61 P71)
边栏推荐
- 日期格式化
- Typescript empty array
- Analyze optimism replay contract address attack events
- WARNING: Your password has expired.Password change required but no TTY available.
- 基于OpenPGP的文件管理系统
- 深入理解机械系统的模态与振动
- Food safety eating preserved eggs will lead poisoning? Don't worry about eating after knowing these points
- A series of specifications of oneplus 10t were disclosed before the product was released
- TYPE-C 转OTG(USB2.0传输数据)+PD充电协议芯片 乐得瑞LDR6028/LDR6023SS
- Mysql: MySQL problem that is not a MySQL problem
猜你喜欢

几何参数化重构

面试官:MySQL 数据库查询慢,除了索引问题还可能是什么原因?

KV260单板PS控制设置IIC开关芯片

为啥一问 JVM 就 懵B ???

Leetcode skimming: dynamic programming 05 (different paths II)

分析optimism重放合约地址攻击事件

乘风破浪!金融科技时代下的数字化转型之路

基于C语言开发的控制台计算器

Transfer business append log (transaction propagation behavior)

Food safety chocolate is also true or false? How much do you know about it
随机推荐
ride the wind and waves! Digital transformation in the era of financial technology
[JS] check whether the date object is invalid date
数据集中度分析,数据分布情况
Why do you get confused when you ask JVM???
LeetCode_455_分发饼干
【flask高级】从源码深入理解flask路由之endpoint
“如今,代码数已膨胀至天文级别”
Can debug/release versions of dynamic library *.dll files be mixed (cross used)?
12 pictures +6k figure ZGC garbage collector and tuning skills
Encapsulate the general connection and query of the project with pymysql
乘风破浪!金融科技时代下的数字化转型之路
Kv260 single board PS control setting IIC switch chip
Summary of stock historical data download interface (dynamic update)
Deeply understand the mode and vibration of mechanical system
转账业务追加日志(事务的传播行为).
Virtual machine network connection mode
Emgu cv3+c # image processing (IV): use emgucv to obtain camera and read video
Kubernetes focuses on kubelet's responsibilities
[flask advanced] deeply understand the endpoint of flask routing from the source code
From Markov chain to GPT, Li Hang, director of ByteDance AI Lab, detailed the past and present lives of language models