rust - 返回实现多个特征的对象 - 装饰器模式
问题描述
我目前正在 Rust 中实现装饰器模式。在 Scala 中,我们可以通过以下特征实现方法链接:
new Scanner
with Whitespaces
with Keywords
我想在 Rust 中做同样的事情。因此,扫描仪的不同特征:
pub struct Lexer();
pub trait Scan {
fn scan(&self, start: &String) -> DomainTags;
}
pub struct Keywords<T> {
decorated: T
}
impl<T: Scan> Scan for Keywords<T> {
fn scan(&self, start: &String) -> DomainTags {
...
}
}
pub struct Whitespaces<T> {
decorated: T
}
impl<T: Scan> Scan for Whitespaces<T> {
fn scan(&self, start: &String) -> DomainTags {
...
}
}
但是由于我想使用以下方法构建我的词法分析器:
pub fn build() -> ??? {
let lex = Lexer();
let lex = Keyword {
decorated: Whitespaces {
decorated: lex
}
};
lex
}
我不知道是否可以将返回类型静态推断为 decltype(lex)
. 实现该方法的常用方法是什么?有什么可以改进的?
澄清一下:我想 return decltype(lex)
,因为我可能对单个 Lexer 也有多个特征,例如:
pub trait Load {
fn load<T : Load>(&self, keywords: &String);
}
impl Load for Lexer {
fn load<Lexer>(&self, keyword : &String) {
...
}
}
我希望返回一个带有 Load trait 实现的装饰对象。方法加载和扫描都应该可用。
解决方案
一个函数只能返回一种类型的值,所以你的函数返回的类型不能依赖于运行时条件。但是,该类型可能是盒装特征,在这种情况下,存储在框中的值的类型可能会改变,只要它实现了适当的特征(或特征)。
从您提供的示例代码中,我认为这Lexer
应该是一个类似的特征trait Lexer: Scan + Load {}
(或者可能根本不需要存在Scan
and特征,并且可以直接在中定义and方法)。那么你的函数应该只返回一个 boxed :Load
scan
load
Lexer
build
Lexer
pub trait Lexer {
fn scan (&self, start: &String) -> DomainTags;
fn load (&self, keyword : &String);
}
pub struct Keywords<T> {
decorated: T
}
impl<T: Lexer> Lexer for Keywords<T> {
…
}
pub struct Whitespaces<T> {
decorated: T
}
impl<T: Lexer> Lexer for Whitespaces<T> {
…
}
pub fn build (cond: bool) -> Box<dyn Lexer> {
if cond {
Box::new (Whitespaces { … })
} else {
Box::new (Keywords { … })
}
}
推荐阅读
- javascript - Javascript fs.readfile() 不保存到变量
- c# - 如何将表和关系添加到生成的 Asp.Net Core MVC Identity 数据库?
- php - PHP, error_log('消息'); 如何在浏览器中检索和显示消息?
- c# - 如何调试涉及方法调用的合并空语句
- quantum-computing - Q#中R1和Rz的区别
- javascript - 如何在js中使用另一个div属性值更改div背景颜色
- database - Cloud Firestore 结构更好的案例
- angular - 如何根据anular中的复选框值过滤firebase数据库
- server - WAMP 服务器指向 IP 地址,现在 IP 地址已更改。我无法再访问我的网站
- java - 服务发送的通知不会显示