Versions/v1.0.5/中文

宏包定义和导入

Sections1
On This Page1
API Symbols1

宏包定义和导入

仓颉语言中宏的定义需要放在由 macro package 声明的包中,被 macro package 限定的包仅允许宏定义对外可见,其他声明包内可见。

> 说明:
>
> 重导出的声明也允许对外可见,关于包管理和重导出的相关概念,请参见包的导入章节。


需要特殊说明的是,在宏包中,允许其他宏包和非宏包的声明被重导出。在非宏包中仅允许非宏包的声明被重导出。

参考如下示例:

- 在宏包 A 中定义宏 M1


编译命令如下:

- 在非宏包 B 中定义一个 public 函数 f1。注意在非 macro package 中无法重导出 macro package 的符号


编译命令如下,这里选择使用 --output-type 选项将 B 包编译成动态库,关于 cjc 编译选项介绍可以参考 "附录 > cjc 编译选项" 章节。

- 在宏包 C 中定义宏 M2,依赖了 A 包和 B 包的内容。可以看到 macro package 中可以重导出 macro package 和非 macro package 的符号


编译命令如下,注意这里需要显式链接 B 包动态库:

- 在 main.cj 中使用 M2


编译命令如下:

main.cjM2 宏展开后的结果如下:

可以看到 main.cj 中出现了来自于 B 包的符号 f1。宏的编写者可以在 C 包中重导出 B 包里的符号,这样宏的使用者仅需导入宏包,就可以正确地编译宏展开后的代码。如果在 main.cj 中仅使用 import C.M2 导入宏符号,则会报 undeclared identifier 'f1' 的错误信息。

cangjie
// file define.cj
macro package define         // 编译 define.cjo 携带 macro 属性
import std.ast.*

public func A() {}          // Error, 宏包不允许定义外部可见的非宏定义,此处会报错

public macro M(input: Tokens): Tokens { // macro M 外部可见
    return input
}