Rust语言之GoF设计模式: 解释器Interpreter模式


解释器模式是  一种设计模式,它指定如何评估语言中的句子。解释器模式描述了如何为简单语言定义语法。

如果一个问题经常发生并且需要很长的重复步骤来解决它,那么问题实例可能会用一种简单的语言来表达,并且解释器对象可以通过解释用这种简单语言编写的句子来解决它。
基本上,对于我们定义的任何类型的问题:

// Interpreter pattern

// Define simple DSL string literal, and parse & execute it.

pub fn interpreter() {
    Interpreter::parse_and_execute(
"3 Mew Waon !");
}

struct Interpreter;

impl Interpreter {
    fn parse_and_execute(s: &str) {
        if let Some(i) = s.find(' ') {
            let (num, word) = s.split_at(i);
// => ("3", " Mew Waon !")
            let word = &word[1..];
// Trim first blank from `word`.
            let times = num.parse::<usize>().unwrap();
            for _ in 0..times {
                print!(
"{} ", word);
            }
            println!();
        }
    }
}

Rust的宏可以看成变种解释器:
Rust 提供了一个强大的宏系统,允许元编程。宏看起来像函数,只是它们的名称以! 结尾,但宏不是生成函数调用,而是扩展为与程序的其余部分一起编译的源代码。但是,与 C 和其他语言中的宏不同,Rust 宏被扩展为抽象语法树,而不是字符串预处理,因此您不会遇到意外的优先级错误。

宏是使用macro_rules!宏创建的:

//// 这是一个名为`say_hello`的简单宏。
macro_rules! say_hello {
      
// `()`表示该宏不需要参数。
    () => {
             
// 该宏将展开为这个块的内容。
        println!(
"Hello!");
    };
}

fn main() {
     
// 这个调用将扩展为 `println!("Hello"); `
    say_hello!()
}

那么为什么宏有用呢?

  1. 不要重复自己。在很多情况下,您可能需要在多个地方使用不同类型的类似功能。通常,编写宏是避免重复代码的有用方法。
  2. 特定领域的语言DSL。宏允许您为特定目的定义特殊语法。
  3. 可变接口。有时您想定义一个接受可变数量参数的接口。一个示例是println!可以采用任意数量的参数,具体取决于格式字符串!

规则引擎 中规则的编写执行也属于一种解释器模式