rust 动态分发 dyn
动态分发编译语言大多会遇到一个问题类型和大小是否能在编译器固定顾名思义动态分发即代表着运行时确定静态分发为编译期就已确定对于大小还好解决将值放在堆上即可解决数据类型大多语言都已支持泛型T以标准库自带的struct Vec来说是由泛型实现的一个宏切片使用时例如let language_cost vec![Rust, Python, Java];泛型体现为Vecstr每个切片的具体值为str这里暂称str类型为基础类型一个完整示例定义一个接口Animal分别定义两个结构体并分别实现Animal接口traitAnimal{fnmake_sound(self);}structDog;implAnimalforDog{fnmake_sound(self){println!(汪汪汪);}}structCat;implAnimalforCat{fnmake_sound(self){println!(喵喵喵);}}声明三种调用方法fndisplay_sound(animal:dynAnimal){animal.make_sound();}fndisplay_static_sounds(animal:implAnimal){animal.make_sound();}fndisplay_generic_soundsT:Animal(animal:T){animal.make_sound();}(这里先不关心所有权问题)display_static_sounds与display_generic_sounds是一样的内部实现都是一样的在main方法中都可以正常调用fnmain(){letdogDog;letcatCat;// display_sound(dog);// display_static_sounds(cat);// display_generic_sounds(cat);}dyn关键字display_sound方法中有一个dyn关键字各大技术博客都解释为动态分发也就在程序运行时才知道其调用的具体方法而不是将泛型或者trait的所有实现在编译器进行打包例如impl Animal程序中有两个struct均实现了该接口编译器在打包时将会生成多份代码执行也就意味着二进制包会大一点但是运行时就会很快使用dyn关键字定义 trait 对象本质上是告诉编译器 “这个类型需要走动态分发函数调用的具体目标要到运行时才能确定如果接触过c了解过vtable就会很好理解但我还是不太理解 。。。切片上面有说到Vec切片内部是使用泛型来实现的fnmain(){letdogDog;letcatCat;letanimals:VecimplAnimalvec![dog,cat];}这里会报个错impl Trait is not allowed in the type of variable bindingsimpl Trait is only allowed in arguments and return types of functions and methods类型impl Trait只能用于方法的形参和返回类型并且泛型在实例化后对于结构体这类非基础类型不是同一种类型虽然都实现了同一个traitdog ! cat切片使用方法fnmain(){letdogDog;letcatCat;letanimals:VecdynAnimalvec![dog,cat];foranimalinanimals{display_sound(animal);}}应用场景自我感觉rust中的dyn设计的不太优雅有些不符合编码预习惯预期dyn关键字大多数都是搭配trait/Box使用什么时候使用动态分配或静态分配这个要取决于自己对编程和项目的理解大多数场景下代码都可以用泛型方式去替代所以说用哪种并没有绝对的对错推荐动态跨模块 / 库的抽象当 trait 的实现者不在当前编译单元如第三方库无法通过泛型静态分发时动态分发是唯一选择。统一存储多类型实例、避免泛型代码膨胀时如数百种类型实现同一个 trait必须使用 dyn 标记 trait 对象需要存储 / 处理不同类型的 trait 实现者如Vecdyn Animal 混合Dog/Cat需要在运行时动态决定使用哪个类型如根据用户输入选择实例需要控制二进制体积避免泛型单态化导致的代码膨胀需要函数返回不同类型的 trait 实现者。推荐静态性能敏感的场景比如游戏引擎、高频计算的代码静态分发无运行时开销性能更优编译时即可确定类型比如工具类函数输入类型固定泛型静态分发更简洁、高效需要避免运行时错误静态分发在编译时检查类型动态分发可能因类型错误导致运行时 panic如 downcast 失败。类型固定、追求极致性能的场景代码简洁性优先且不需要异构集合 / 动态类型切换的场景。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2445378.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!