1 个不稳定版本
0.1.0 | 2023 年 7 月 28 日 |
---|
#1324 在 Rust 模式
185KB
275 行
Hereditary
通过扩展基于其组合(因为它们包含实现所需功能的其他类型的实例)的结构体中的特性功能,在 Rust 中模拟面向对象继承的进程宏。
Hereditary
通过 转发 其结构体字段中引用的包含实例所实现的所需方法,生成组合结构体特性实现的样板代码。
目前,Hereditary
支持 2 种委托类型
- 部分委托:通过在特性实现上使用装饰器属性
#[forward_trait(submember)]
。 - 完全委托:通过在组合结构体上应用
#[derive(Forwarding)]
,它从属性#[forward_derive(Trait)]
派生出特性实现(指定为属性)。
注意
在此处的文档页面中了解更多信息 https://docs.rs/hereditary
特性
- 通过一条指令在组合结构体上实现子类型多态,将新类型赋予与其组件相同的接口。
- 重用其他类型的字段/方法实现作为子组件,无需重复编写转发这些子组件方法的自定义代码。
Hereditary
工具本质上是一种 零成本抽象。它们不需要运行时结构来存储特性类型信息。所有工作都由宏和代码生成完成。- 有效地拥抱 新类型模式,但无需像以前那样繁琐地重新实现
inner-type
接口。通过使用这种技术,Rust 程序员可以避免将新行为整合到现有外部类型时的问题,绕过 特质孤儿规则。
用法
在您的仓库中安装
cargo add hereditary
在您的代码中插入 hereditary
宏
mod animal {
// Attribute macro for generating trait info
#[hereditary::trait_info]
pub trait Cannis {
fn bark(&self)-> String;
fn sniff(&self)-> bool;
}
#[hereditary::trait_info]
pub trait Bird {
fn sing(&self) -> String;
fn fly(&mut self, elevation:f64) -> f64;
}
}
// Heritance for an hybrid animal
#[derive(hereditary::Forwarding)]
struct KimeraSphinx
{
#[forward_derive(animal::Cannis)] // full implementation of Cannis
dogpart:Bulldog,
birdpart:Seagull
}
// Combining existing trait implementation from Seagull instance
#[hereditary::forward_trait(birdpart)]
impl animal::Bird for KimeraSphinx
{
fn sing(&self) -> String
{
self.dogpart.bark()
}
}
// -- Subcomponent implementations -- //
struct Bulldog { position:f64 }
impl animal::Cannis for Bulldog {
//... Cannis methods ...
}
struct Seagull { elevation:f64 }
impl animal::Bird for Seagull {
//... Bird methods ...
}
fn main() {
// Instance kimera
let mut kimera = KimeraSphinx::new();
// A dogs that flies.
assert_eq!(kimera.fly(50f64), 50f64);
assert_eq!(kimera.bark(), kimera.sing()); // It barks instead of singing
assert_eq!(kimera.sniff(), true);
}
限制
- 由于宏的使用非常频繁,使用
Hereditary
生成的代码会经历更长的编译过程。 - 有时,外部模块无法引用特质信息,因为生成的
trait_info
宏不像其对应的特质那样自动导入。这就是为什么它们需要在使用转发属性时使用完整路径(例如animal::Bird
),而不是仅仅使用Bird
。这是与声明性宏及其可见性作用域规则相关的一个已知问题,因为当将它们作为模块符号 导出时,它们有特殊的需求。
许可证
Apache 2.0
作者: Francisco Leon
依赖项
~1.5–2MB
~29K SLoC