5 个版本
0.1.4 | 2023 年 3 月 29 日 |
---|---|
0.1.3 | 2022 年 5 月 15 日 |
0.1.2 | 2022 年 5 月 15 日 |
0.1.1 | 2022 年 5 月 5 日 |
0.1.0 | 2022 年 5 月 5 日 |
在 Rust 模式 中排名 #874
每月下载量 87
用于 entrait
13KB
实现
一个用于定位和访问实际实现的包。
举一个示例特性
trait ScrapeTheInternet {
fn scrape_the_internet(&self) -> Vec<Website>;
}
这个特性代表一些抽象计算。特性导出一个可以被类型实现的方法签名。在这种情况下,我们可以想象这个特性的真实实现会做什么:实际上抓取互联网。
实现
提供了 [Impl] 类型作为具有以下语义的特性实现目标
- 特性只有一个实际、真实实现。
- 其他特性的实现可能存在,但这些被解释为以某种方式伪造、模拟。
实现
允许以标准化的方式编写这些实际实现,从而允许实际的 Self
接收者类型未知。
使用方法
要定义 ScrapeTheInternet
的实际、泛型实现,我们可以编写以下 impl
impl<T> ScrapeTheInternet for implementation::Impl<T> {
fn scrape_the_internet(&self) -> Vec<Website> {
todo!("find all the web pages, etc")
}
}
此代码为 [Impl] 实现了特性,通过这种方式我们断言它是实际、真实实现。
该实现是全泛型的,适用于任何 T
。
use implementation::Impl;
struct MyType;
let websites = Impl::new(MyType).scrape_the_internet();
特性界限
保持特性实现泛型的优点是,self 类型可能位于下游包中。假设我们需要从 scrape_the_internet
访问配置参数。例如,抓取的最大页面数
use implementation::Impl;
trait GetMaxNumberOfPages {
fn get_max_number_of_pages(&self) -> Option<usize>;
}
impl<T> ScrapeTheInternet for Impl<T>
where Impl<T>: GetMaxNumberOfPages
{
fn scrape_the_internet(&self) -> Vec<Website> {
let max_number_of_pages = self.get_max_number_of_pages();
todo!("find all the web pages, etc")
}
}
为了使此功能正常工作,Impl<T>
还需要为相同的 T
实现 GetMaxNumberOfPages
(将要使用的相同 T
)。
GetMaxNumberOfPages
可能会针对特定的 T
实现,而不是泛型,因为该 T
通常是一些包含该数字的配置
struct Config {
max_number_of_pages: Option<usize>
}
impl GetMaxNumberOfPages for implementation::Impl<Config> {
fn get_max_number_of_pages(&self) -> Option<usize> {
self.max_number_of_pages
}
}
解释
此包是解决特性一致性问题的解决方案。
给定上述特性,我们希望提供一个实际和模拟实现。我们可能知道其实际实现看起来像什么算法,但我们不知道应该为哪种类型实现。有多个原因要有一个泛型的 Self
- Self 类型可能位于下游包中
- 它实际上是为泛型设计的
如果我们使用了通用的Self类型(impl<T> DoSomething for T
),则特工会失去拥有不同伪造实现的能力,因为这会违反一致性规则:通用的(“空白”)实现和特殊化实现不能同时存在,因为这会导致歧义。
为了解决这个问题,需要一个具体类型作为实现目标。但这种类型允许在内部是通用的。只需要在根级别使用具体的命名类型。
这个类型是[Impl]类型。
当我们使用这种实现时,我们可以创建尽可能多的伪造实现。
许可证:MIT