2 个不稳定版本
0.2.0 | 2020 年 3 月 12 日 |
---|---|
0.1.0 | 2020 年 3 月 9 日 |
5 在 #upcast
每月下载量 6,853
38KB
939 行
一个属性宏,用于生成从特质对象中检索超特质的函数(向上转换)。
如果你有一个具有超特质的特质,有时你可能想要将特质对象向上转换。Rust 当前不支持此操作。
trait Super {}
trait Sub: Super {}
fn wants_upcast(sub: Box<dyn Sub>) {
let s: Box<dyn Super> = sub;
// do something with super.
}
这会导致以下错误
error[E0308]: mismatched types
--> src/lib.rs:27:29
|
8 | let s: Box<dyn Super> = sub;
| -------------- ^^^ expected trait `Super`, found trait `Sub`
| |
| expected due to this
|
= note: expected struct `std::boxed::Box<dyn Super>`
found struct `std::boxed::Box<(dyn Sub + 'static)>`
error: aborting due to previous error
as_dyn_trait 属性解决了这个问题
#[as_dyn_trait]
trait Super {}
trait Sub: Super {}
fn wants_upcast(sub: Box<dyn Sub>) {
// s has type Box<dyn Super>.
let s = sub.as_dyn_super();
// do something with super.
}
为此,宏生成几个特质。对于一个名为 MyTrait
的特质,这些特质的名称和它们的方法是
AsDynMyTraitRef
:fn as_dyn_my_trait(&self) -> &dyn MyTrait;
fn as_dyn_my_trait_mut(&mut self) -> &mutdyn MyTrait;
AsDynMyTraitBox
:fn as_dyn_my_trait(self: Box<Self>) -> Box<dyn MyTrait>;
AsDynMyTraitRc
:fn as_dyn_my_trait(self: Rc<Self>) -> Rc<dyn MyTrait>;
AsDynMyTraitArc
:fn as_dyn_my_trait(self: Arc<Self>) -> Arc<dyn MyTrait>;
AsDynMyTraitPinRef
:fn as_dyn_my_trait(self: Pin<&Self>) -> Pin<&dyn MyTrait>;
fn as_dyn_my_trait_mut(self: Pin<&mut Self>) -> Pin<&mutdyn MyTrait>;
AsDynMyTraitPinBox
:fn as_dyn_my_trait(self: Pin<Box<Self>>) -> Pin<Box<dyn MyTrait>>;
AsDynMyTraitPinRc
:fn as_dyn_my_trait(self: Pin<Rc<Self>>) -> Pin<Rc<dyn MyTrait>>;
AsDynMyTraitPinArc
:fn as_dyn_my_trait(self: Pin<Arc<Self>>) -> Pin<Arc<dyn MyTrait>>;
这些特质自动为所有实现 MyTrait
的 Sized
类型实现。如果你想要为动态大小类型实现 MyTrait
,你需要手动添加这些实现。由于你不能将 DST 转换为特质对象,因此这种实现总是会导致 panic。
为了使这些特质能够在特质对象上工作,它们都是 MyTrait
的自动超特质。
该属性支持几个选项。选项作为逗号分隔的列表传递给属性
#[as_dyn_trait(enable_pin = true, trait_name_prefix = DifferentName)]
trait Super {}
trait_name_prefix
:用于生成的特质的命名前缀。默认是AsDyn
后跟特质名称。ref_trait_name
:引用特质的名称。默认是带有后缀Ref
的特质名称前缀。box_trait_name
:用于Box
的特质的名称。默认是带有后缀Box
的特质名称前缀。rc_trait_name
:用于Rc
的特质的名称。默认是带有后缀Rc
的特质名称前缀。arc_trait_name
:用于Arc<_>
的特名字符串。默认是在特名字符串前加上Arc
。pin_ref_trait_name
:用于Pin<_>引用的特名字符串。默认是在特名字符串前加上PinRef
。pin_box_trait_name
:用于Pin<Box<_>>
的特名字符串。默认是在特名字符串前加上PinBox
。pin_rc_trait_name
:用于Pin<Rc<_>>
的特名字符串。默认是在特名字符串前加上PinRc
。pin_arc_trait_name
:用于Pin<Arc<_>>
的特名字符串。默认是在特名字符串前加上PinArc
。method_name
:转换方法的名称。默认是as_dyn_
后跟特名字符串(转换为小写蛇形)。mut_method_name
:可变引用转换方法的名称。默认是as_dyn_
后跟特名字符串(转换为小写蛇形)和_mut
。enable_ref
:启用引用的转换。默认为true。enable_box
:启用Box<_>
的转换。默认为true。enable_rc
:启用Rc<_>
的转换。默认为true。enable_arc
:启用Arc<_>
的转换。默认为true。enable_pin
:启用Pin<_>
类型的转换。这些转换仅在相应的基指针转换也被启用的情况下生成。默认为false。
此属性不使用或生成任何不安全代码。
依赖项
~1.5MB
~34K SLoC