rust - 返回实现多个特征的对象——装饰器模式

标签 rust decorator traits decltype

我目前正在用 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) 的类型。实现该方法的常用方法是什么?哪些地方可以改进?

澄清一下:我想返回 decltype(lex),因为对于单个 Lexer,我可能还具有多个特征,例如:

pub trait Load {
    fn load<T : Load>(&self, keywords: &String);
}

impl Load for Lexer {
    fn load<Lexer>(&self, keyword : &String) {
       ...
    }
}

而且我希望返回一个实现了 Load 特性的装饰对象。方法加载和扫描都应该可用。

最佳答案

一个函数只能返回一种类型的值,因此您的函数返回的类型不能依赖于运行时条件。然而,该类型可能是装箱特征,在这种情况下,存储在框中的值的类型可能会改变,前提是它实现了适当的特征(或多个特征)。

根据您提供的示例代码,我认为 Lexer 应该是一个类似 trait Lexer: Scan + Load {} 的特征(或者可能是 ScanLoad traits 根本不需要存在,scanload 方法可以直接在 词法分析器)。然后你的 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 { … })
    }
}

关于rust - 返回实现多个特征的对象——装饰器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55913476/

相关文章:

rust - 返回本地String作为切片(&str)

string - 如何在多个分隔符上拆分字符串(String 或 &str)?

ruby-on-rails - 如何使用同一张表为一组模型创建装饰器?

javascript - 为什么我们不在 app.module.ts 的装饰器数组中添加 'ngModule'

rust - 发生移动是因为值的类型为Vec <T>,该类型未实现 `Copy`特征

rust - Into<PathBuf> 的多个泛型

python - 为多个属性定义@property 的函数

rust - 如何在实现 Debug 时访问指定的精度?

scala - 通过使用 traits 和 with 关键字来减少代码

syntax - 特征中的静态函数可以调用同一特征中的另一个静态函数吗?