那时候写 C++。
你一进项目。
先看见一堵墙。
全是 #include。
你以为这只是“引用头文件”。
后来你才知道。
这是在做文本拼接。
当年:#include 只是复制粘贴
#include 的本质。
就是把另一个文件的内容。
原封不动塞进来。
编译器看到的。
不是“模块依赖”。
是一个巨大的源文件。
所以你会遇到这些老问题。
编译越来越慢。
宏到处乱飞。
头文件顺序一换就报错。
线上啪一下:改了一个头文件,整个项目开始玄学
你写个小项目。
加了个宏。
// a.h
#define min(a,b) ((a) < (b) ? (a) : (b))
你以为只是给自己用。
然后你在另一个文件里。
写了 std::min。
#include <algorithm>
auto x = std::min(1, 2);
它就开始报错。
你看半天。
才发现你把 min 这个名字污染了。
而且污染是“全局的”。
你只要 include 过。
就甩不掉。
Modules 的想法:把“接口”从“实现”里分离出来
模块做的第一件事。
不是更酷。
是更严格。
你不再靠文本拼接。
你有了一个明确的“导出接口”。
导出的名字。
才是别人能看到的名字。
没导出的。
别人看不到。
一个最小模块
你先看语法。
export module math;
export int add(int a, int b) {
return a + b;
}
export module math; 是模块声明。
export 的东西。
就是接口。
使用模块
import math;
int main() {
return add(1, 2);
}
你注意到了。
这里不是 #include。
是 import。
它不是复制文本。
它是依赖一个已编译好的模块接口。
你刚学 C++ 会皱眉:这和头文件有什么区别
头文件时代。
你“看到什么”。
取决于 include 顺序。
还取决于宏。
模块时代。
你“看到什么”。
取决于模块明确导出的接口。
顺序不该改变语义。
关键结论
Modules 不是为了写得更花。
它是为了让依赖更像依赖。
而不是像拼接。
小结
你可以把模块理解成。
标准化的“可编译头文件”。
它把过去那些靠约定维持的秩序。
变成了语言规则。