8 个稳定版本
3.1.0 | 2024年4月21日 |
---|---|
3.0.1 | 2024年4月5日 |
3.0.0 | 2024年3月26日 |
2.0.3 | 2024年3月10日 |
1.0.0 | 2024年2月26日 |
#9 in #delegation
79 每月下载量
用于 sux
95KB
3K SLoC
该 crate 提供了一般机制,通过转发其他类型提供的实现来在类型上实现特性。
提供了两种不同的转发方法:通过成员实现的特性转发,以及通过可以将接收者类型转换为的类型实现的特性转发。这些方法可以在同一接收者类型上组合使用。此 crate 完全支持泛型特性和结构体类型。
有关更多详细信息,请参阅 crate 文档。
lib.rs
:
该 crate 提供了一般机制,通过转发其他类型提供的实现来在类型上实现特性。
提供了两种不同的转发方法:通过成员实现的特性转发,以及通过可以将接收者类型转换为的类型实现的特性转发。这些方法可以在同一接收者类型上组合使用。此 crate 完全支持泛型特性和结构体类型。
有关功能和限制的更多详细信息,请参阅各个宏的文档页面。
基础
为了转发一个特性,需要一些基本的东西。
use forward_traits::{forwardable, forward_receiver, forward_traits};
我们需要一个特性定义,该定义带有用于生成转发实现的信息。这是通过将 #[forwardable]
属性应用于定义来完成的。
#[forwardable]
trait FooTrait
{
type Bar;
fn foo (&self) -> &Self::Bar;
const BAZ: u32;
}
然后我们需要一个最初实现此特性的类型。
struct A {}
impl FooTrait for A
{
type Bar = Self;
fn foo (&self) -> &Self::Bar { self }
const BAZ: u32 = 42;
}
接下来,我们需要一个类型,我们想要通过转发在最初实现类型上找到的实现来实现此特性。有几种不同的方法来定义此类类型,但在这里我们将演示 newtype 习惯用法。此类型需要带有 #[forward_receiver]
属性。
#[forward_receiver]
struct B (A);
最后,我们需要指定我们想要转发一个特性。在这种情况下,我们想要转发由成员实现的特性,所以我们写
forward_traits! (for B . 0 impl FooTrait);
现在我们可以看到特性已正确转发。
assert_eq! (<B as FooTrait>::BAZ, 42);
重新导出可转发特性
在重新导出可传递特性时,应将 #[forwardable]
属性应用于使用语句。请注意,该属性将解释使用树中的每个项作为应可传递的特性。如果您想从同一模块(或模块集)中重新导出不是可传递特性的项,则需要将这些重新导出分开到另一个使用语句中;
use forward_traits::forwardable;
mod inner
{
use forward_traits::forwardable;
#[forwardable]
pub trait Foo {}
pub struct Bar {}
}
#[forwardable]
pub use inner::Foo;
pub use inner::Bar;
其他包中的特性
可传递特性与在其他包中的特性一起工作,只要这些特性定义注解了 #[forwardable]
。
如果没有,则必须单独提供注解。以这种方式提供注解时,特性将在注解宏的位置导入(如果提供了可见性修饰符,则重新导出)。在转发此特性时,您必须引用此导入/导出(或其重新导出)。
use forward_traits
::{
supply_forwarding_info_for_trait,
forward_receiver,
forward_traits
};
// This has the side-effect of importing IntoIterator into the current scope.
supply_forwarding_info_for_trait!
(
std::iter::IntoIterator,
trait
{
type Item;
type IntoIter;
fn into_iter (self) -> Self::IntoIter;
}
);
#[forward_receiver]
struct VecWrapper <T> (Vec <T>);
// Note that we are referring to the IntoIterator in the current scope.
forward_traits! (for VecWrapper . 0 impl IntoIterator);
// Now we can call the trait method on the wrapper type.
VecWrapper (vec! (1, 2, 3)) . into_iter ();
依赖项
~320–780KB
~18K SLoC