《领域特定语言》一3.5 宏

简介: 本节书摘来自华章出版社《领域特定语言》一书中的第3章,第3.5节,作者 (英)Martin Fowler,更多章节内容可以访问云栖社区“华章计算机”公众号查看

3.5 宏

“宏”(第15章)是一种工具,既可以用于内部DSL,也可以用于外部DSL。宏曾经得到广泛应用,但如今已不那么常见了。在大多数情况下,我建议尽量避免使用宏,但偶尔,它也有一些用处。所以,接下来,就谈论宏的运作方式以及使用时机。
宏有两种风格:文本宏和语法宏。文本宏最容易理解,简单说就是文本替换。使用文本宏会带来便利,一个很好的例子就是,在CSS文件中指定颜色。除了少数几种特定情况外,CSS强制我们以颜色代码指定颜色,比如#FFB595。这样的代码并不表意,更糟糕的是,如果要在多个地方使用同一种颜色,就要重复同样的代码。任何形式的代码重复都是坏味道。我们可以给它一个在上下文中有意义的名字,比如MEDIUM_SHADE,在一个地方定义它,比如,MEDIUM_SHADE等于#FFB595。
虽然CSS(至少目前为止)并不允许这么做,但可以用一个宏处理器处理这种情况。创建一个文件,它就是CSS文件,只不过其中用MEDIUM_SHADE表示所需的颜色。然后,用宏处理器做一次简单的文本替换,把MEDIUM_SHADE替换为#FFB595。
这只是一个非常简单的宏处理例子。更复杂的宏还可以有参数。一个经典的例子是C的预处理器,比如,定义一 个宏sqr(x),它可以替换为x*x。
通过宏创建DSL有很多方式,可以使用宿主语言本身(比如,C预处理器),也可以提供单独的一个文件,将其转换为宿主语言。宏的缺点在于,它有很多诡异的问题,这使得它在实际中难于使用。所以,文本宏现在已经不再受宠,很多专业人士(比如我)都反对使用它。
语法宏也是通过替换实现的,但是它处理的是宿主语言中有效的元素,将一种表达式转换为另一种。在以“大量使用语法宏”而闻名的语言中,Lisp最为著名,虽然C++模板更广为人知。使用语法宏编写DSL,是Lisp编写内部DSL 的核心技术,但这种技术也仅限于支持宏的语言。因此,本书不会过多谈及,因为仅有很少的语言可以支持宏。

相关文章
|
14天前
|
C语言
|
1月前
|
程序员 C语言
C语言 宏
C语言 宏
14 0
|
2月前
|
Rust 编译器 开发者
Rust中的进阶宏:派生宏与属性宏
本文将深入探讨Rust编程语言中的派生宏(Derive Macros)和属性宏(Attribute Macros)这两种进阶宏的用法。派生宏用于自动生成实现特定trait的代码,而属性宏则允许我们为模块、函数、结构体等添加自定义属性。我们将通过实例展示如何在Rust项目中使用这些高级宏来增强代码的可读性和可维护性。
|
2月前
|
Rust 安全 编译器
Rust宏基础:定义与使用
本文将深入探讨Rust编程语言中的宏(Macros)基础,包括其定义、使用场景以及如何编写自定义宏。我们将从宏的基本概念出发,逐步深入到具体的实现细节,并通过实例展示如何在Rust项目中使用宏来简化代码和提高效率。
|
2月前
|
Rust 安全 编译器
Rust中打印语句为什么使用宏?
在Rust中,打印语句使用宏(例如`println!`和`format!`)的主要原因是为了在编译时进行字符串格式检查,并在不引入运行时开销的情况下提供更高的性能和安全性。宏可以被多次调用,这样你可以在不同的地方重复使用相同的代码模式。这有助于减少代码重复,提高代码的可维护性。
|
17天前
|
编译器 C语言
C语言中函数宏的三种封装方式详解
C语言中函数宏的三种封装方式详解
47 0
|
8月前
|
C++
C++宏 #与##的区别
C++宏 #与##的区别
35 0
|
8月前
|
C语言
|
9月前
|
C语言 C++
【C语言】宏vs函数谁更简便
【C语言】宏vs函数谁更简便
|
10月前
|
Rust 编译器 开发者
Rust中的过程宏
Rust中的过程宏