let obj = return_trait_object(); obj.do_something(); } 在上面的代码中,我们定义了一个特征MyTrait和一个结构体MyStruct,并为MyStruct实现了MyTrait。然后,我们定义了一个函数return_trait_object,它返回一个Box<dyn MyTrait>,即一个特征对象的盒子。在main函数中,我们调用return_trait_object并...
前面说过,trait object 允许一个值有不同的类型,只要这个类型实现了特定的 trait。有无数种可能性,...
impl Trait:静态分发 dyn Trait:动态分发 静态分发:在编译期就确定了具体返回类型,函数只能返回一种类型。 动态分发:在运行时才能确定具体返回类型,函数可以返回多种类型。 Trait Object:指向trait的指针,假设Animal是一个triait,那么&Animal和Box<Animal>都是一种Trait Object。 胖指针:用于指代动态大小类型(DST)的...
Pointers to trait objects also store a pointer to a vtable. 这里引出了两个重要的概念,胖指针(fat pointer),即DST的指针的大小是普通指针的两倍,对slice来说,一个指针存地址,另一个指针存slice的长度;对trait object来说,一个指针存地址,另一个指针存虚表(vtable)。 看起来我们终于接触到了动态类型系统的...
Box<dyn Error> 类型是一个trait 对象(trait object)第16节 顾及不同类型值的 trait 对象”:https://kaisery.github.io/trpl-zh-cn/ch17-02-trait-objects.html#顾及不同类型值的-trait-对象部分会做介绍。目前可以将 Box<dyn Error> 理解为 “任何类型的错误”。在返回 Box<dyn Error> 错误类型 main 函...
impl_downcast!(MyTrait); 之后使用就可以很简单地调用downcast来实现向下转换了: ifletSome(my_impl)=my_trait_object.downcast::<MyImpl>(){// ...逻辑} 补充:想起来这个方法还有一个优势,就是可以让编译器检查转换的类型是否为实现了该trait类型。
A trait object is an opaque value of another type that implements a set of traits. The set of traits is made up of an object safe base trait plus any number of auto traits. 比较重要的一点是 trait object 属于 Dynamically Sized Types(DST),在编译期无法确定大小,只能通过指针来间接访问,常见的...
特征对象(Trait Object):类似于C++里的多态 ,后面我们会通过具体例子来讲解。 其他:由于本文探究Rust常见数据类型,因此本文不关注自定义DST和外部类型。 [T]与str 首先我们看切片与str,我们通过std::mem::size_of查看不同类型的输出,可以看到因为&u32与&[u32;2]的大小在运行时可知,因此Rust编译器认为其为普通...
error[E0746]:returntype cannot have an unboxed trait object--> src/main.rs:144:24 | 144 | fn return_closure() -> Fn(i32) ->i32 {| ^^^ doesn't have a size known at compile-time 错误又一次指向了Sized trait! Rust并不知道需要多少空间来储存闭包。不过我们在之前了解到这种情况的解决方法...
Trait 对象是动态分发,它在运行时根据对象的实际类型调用方法;而泛型是静态分发,它在编译时就确定了调用的方法。 Trait 对象可以包含不同类型的对象,因为它们的大小是相同的(由指针大小决定);而泛型必须在编译时确定类型,因此要求所有对象的类型都相同。