Rust基础-关于trait之六,动态派发和静态派发的区别

先看代码:

trait myTrait{
    fn tr1(&self);
    fn tr2(&self);
}
struct cat{i:u8,}
struct dog{i:u8,}
impl myTrait for cat {
    fn tr1(&self) { }
    fn tr2(&self) { }
}
struct bear{i:u8,}
impl myTrait for bear {
    fn tr1(&self) { }
    fn tr2(&self) { }
}
impl myTrait for dog {
    fn tr1(&self) {}
    fn tr2(&self) { }
}
fn fun_impl(arg:impl myTrait){ arg.tr1();arg.tr2();}
fn fun_dyn(arg:&dyn myTrait){arg.tr1();arg.tr2();}
fn main() {
    let c=cat{i:1};
    let d=dog{i:1};
    fun_impl(c);
    fun_impl(d);

    let c1=cat{i:1};
    let d1=dog{i:1};
    fun_dyn(&c1);
    fun_dyn(&d1);

 }

一个trait:myTrait,三个struct: dog,bear,cat, 两个函数:fun_impl(静态派发调用),fun_dyn(动态派发调用)

为了说明问题,把这段代码转成汇编,

一、先看静态派发的fun_impl如下图

1、先在main里调用了2次

2、在程序体内分别为dog和cat生成一次

至于没有为bear生成,是因为在main里没有调用,编译器自动忽略了。这就是静态派发,就是把可能用到的trait function全部帮你提前静态生成,好处在于快,通过单态化, 编译器消除了泛型缺点是过多展开可能会导致编译生成的二级制文件体积过大。以上例子是用于函数参数的形式,同样适用于函数返回的情形,类似于:fn do(...) -> impl SomeTrait

二、再看动态派发的fun_dyn如下图

1、同样也在main里调用两次

 2、但在程序体内只生成了一次

 顺便提一句:callq 这两句,分别是24,32,还记得吗我在Rust基础-关于trait之四-不得不说一下rust fat point探索rust的fat point 原理https://blog.csdn.net/DarcyZ_SSM/article/details/124351982

这篇中提到的前3个是固定生成的第四个开始就是自定义的部分,代码分别定义了tr1()和tr2(),所以是24和32.

小小的深入一下,继续:

其中的unnamed_1 和unnamed_2,就是两次fun_dyn函数调用前的参数压栈,编译器已经帮忙把vtable准备好了。下面的截图就是。rust/src/librustc_codegen_llvm/meth.rs

 那动态派发有啥用呢?

考虑下列代码:

fn fun(p1: i32) -> impl View {
    if param1 > 10{
        
        return Circle {};
    } else {
       
        return Square{};
    }
}

以上代码会出错,虽然Circle和Square都实现了View,但rust编译器需要返回大小一致,所以类型不同,大小自然不同。那么把静态的改成动态的指针就Ok了,如下。

fn fun(p1: i32) -> Box<dyn View> {
    if param1 > 10{
        
        return Box::new(Circle {});
    } else {
       
        return Box::new(Square{});
    }
}

 相关文章:

Rust基础-关于trait之一_DarcyZ_SSM的博客-CSDN博客

Rust基础-关于trait之三_DarcyZ_SSM的博客-CSDN博客

Rust基础-关于trait之四-不得不说一下rust fat point_DarcyZ_SSM的博客-CSDN博客

Rust基础-关于trait之五_DarcyZ_SSM的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值