Carbon 语言入门:10 分钟搭好工具链,C++ 开发者迁移新语言
【免费下载链接】carbon-langCarbon Language's main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang
如果你手头的 C++ 代码库已经膨胀到模板报错翻两屏、改一行头文件就要重编半小时的程度,Carbon 语言值得你花一个下午验证一下。这是 Google 团队主导、定位"C++ 继任者"的实验性语言,主打与现有 C++ 双向互操作。这篇入门教程从工具链搭建讲起,带你 10 分钟内写出第一个 Carbon 程序,并跑通一个完整小项目。
一张表看清 Carbon 站在哪
先说清定位,再决定要不要投入时间。Carbon 不是"又一个系统语言",它的整个设计围绕"让现有 C++ 代码库逐步换轨"展开。
| 维度 | C++ | Rust | Carbon |
|---|---|---|---|
| 性能 | 极高 | 高 | 对标 C++,基于 LLVM 代码生成 |
| 与 C++ 互操作 | — | 需要 FFI 桥 | 设计目标之一,从继承到模板都覆盖 |
| 迁移路径 | — | 通常需重写 | 提供源代码级翻译路线 |
| 学习曲线(对 C++ 开发者) | — | 陡 | 平缓,语法刻意保持熟悉感 |
| 成熟度 | 工业级 | 工业级 | 实验阶段,0.1 版目标尚在路上 |
官方对 Carbon 的概括是三点:性能对齐 C++、与 C++ 双向无缝互操作、对 C++ 开发者友好的学习曲线。README 里还举了一个类比:JavaScript 之于浏览器生态推出了 TypeScript,Java 生态迎来了 Kotlin,Carbon 想填的就是 C++ 生态这个位置。
10 分钟搭好工具链并跑通第一个程序
这节给出唯一推荐路径:装依赖 → 拉代码 → 用 Bazel 构建 → 运行示例。想省事可以下载官方 nightly 工具链压缩包(仅支持较新的 Ubuntu/Debian/WSL 等平台),本文不展开。
# 1. 安装构建工具链的四个依赖(Debian/Ubuntu) sudo apt update sudo apt install clang libc++-dev libc++abi-dev lld # 2. 获取源码 git clone https://gitcode.com/GitHub_Trending/ca/carbon-lang cd carbon-lang # 3. Bazel 构建工具链并打印 help,确认构建成功 ./scripts/run_bazelisk.py run //toolchain -- help第一条命令执行较久(首次会拉取 Bazel 及其依赖),耐心等。看到help的用法说明输出,说明工具链已就绪。
写第一个程序,直接照抄仓库里的 examples/hello_world.carbon:
import Core library "io"; // 导入 IO 库,等价于模块系统的 #include fn Run() { // 程序入口是 Run 而非 main Core.PrintStr("Hello world!\n"); }编译、链接、运行三步(构建产物在bazel-bin下):
./bazel-bin/toolchain/carbon compile --output=hello.o examples/hello_world.carbon ./bazel-bin/toolchain/carbon link --output=hello hello.o ./hello终端输出:
Hello world!看到这一行,工具链和语言就跑通了。
和 C++ 写起来最大的三个不同
熟悉 C++ 后上手 Carbon,真正影响手感的是下面三处。对比来自仓库内的真实代码:examples/sieve.carbon 与 examples/hello_world.carbon。
| 维度 | C++ | Carbon |
|---|---|---|
| 代码组织 | #include头文件 | 模块 +import声明 |
| 变量声明 | int x = 0;/auto x = 0; | var x: i32 = 0;(可写auto推断) |
| 可变对象方法调用 | obj.mutate(),指针隐式 | ref self显式声明,读法默认不可变 |
1. 模块取代头文件。仓库里的示例开头都是import Core library "io";这样的声明,依赖关系在编译期显式可见,不再有包含顺序问题。
2. 入口函数是Run。没有main,fn Run()即程序入口;返回值类型为i32时可作为进程退出码,例如 examples/sieve.carbon 的fn Run() -> i32。
3. 可变性必须显式声明。修改对象的方法要把self标成ref self:
fn MarkMultiplesNotPrime(ref self, p: i32) { // ref 表示需要可变访问 var n: i32 = p * 2; while (n < 1000) { self.is_prime[n] = false; n += p; } }let声明不可变绑定,var声明可变变量,这一点与 C++ 的const习惯刚好反过来:可变是特例,需要写出来。
完整小项目:1000 以内的素数筛
前面验证了工具链,现在按"目标 → 思路 → 代码 → 运行"走一个端到端例子。
目标:筛出 1000 以内所有素数,打印每个,并把总数作为Run的返回值。
思路(共 4 步):
- 用固定长度布尔数组标记候选数,初始全部视为素数;
- 从 2 开始遍历,遇到素数就把它从 2 倍起的倍数全部标记掉;
- 用一个计数器累计命中的素数;
- 返回计数,顺便演示退出码用法。
代码(取自 examples/sieve.carbon,保留关键行注释):
import Core library "io"; class Sieve { impl as Core.UnformedInit {} // 声明默认构造能力 fn Make() -> Sieve { returned var s: Sieve; // 声明将要返回的变量 for (n: i32 in Core.Range(1000)) { s.is_prime[n] = true; // 初始全部标记为素数 } return var; // 直接返回名为 var 的变量 } fn MarkMultiplesNotPrime(ref self, p: i32) { var n: i32 = p * 2; while (n < 1000) { self.is_prime[n] = false; // 划掉 p 的倍数 n += p; } } var is_prime: array(bool, 1000); // 定长数组,1000 个 bool } fn Run() -> i32 { var s: Sieve = Sieve.Make(); var number_of_primes: i32 = 0; for (n: i32 in Core.InclusiveRange(2, 999)) { // 含端点遍历 if (s.is_prime[n]) { ++number_of_primes; Core.Print(n); s.MarkMultiplesNotPrime(n); } } return number_of_primes; }运行:
./bazel-bin/toolchain/carbon compile --output=sieve.o examples/sieve.carbon ./bazel-bin/toolchain/carbon link --output=sieve sieve.o ./sieve输出是 2 开始的一列素数,最后一行为 997:
2 3 5 7 ... 967 971 977 983 991 997用echo $?查看退出码,得到 168,也就是 1000 以内素数的个数。
进阶:三个值得继续深入的特性
每个特性一句话说明价值,细节交给仓库里的官方文档。
定义检查的泛型:泛型定义在写的时候做完整类型检查,不再依赖"实例化时才算数",报错信息也更直接;同时保留了模板机制用于对接 C++。写法参考 examples/advent2024/sort.carbon:
interface Ordered { fn Less(self, other: Self) -> bool; } impl i32 as Ordered { fn Less(self, other: Self) -> bool { return self < other; } }深入阅读:docs/design/generics、docs/design/templates.md。
C++ 互操作:
import Cpp即可调用 C++ 函数和标准库,迁移时新旧代码可在同一工程里共存。真实例子见 examples/interop/cpp/hello_world.carbon:import Cpp library "<cstdio>"; // 导入 C++ 头文件对应的库 Cpp.puts(Cpp.std.data("Hello world!\0")); // 调用 C 标准库设计理念见 docs/design/interoperability/philosophy_and_goals.md。
内存安全路线:规划为两步——先把 C++ 代码高自动化地迁到 Carbon 方言,再渐进式引入内存安全写法;剩余未定义行为会用可见的
unsafe语法显式标注。设计文档在 docs/design/safety。
资源导航:接下来看哪里
以下路径均在仓库内,按需取用:
- 语言规范:docs/spec;设计文档总入口:docs/design
- 入门示例:examples(含
hello_world.carbon、sieve.carbon),进阶练习看 examples/advent2024,15 道已实现题配完整解法 - 编译器与工具链:toolchain,架构说明在 toolchain/docs/README.md
- 项目目标与路线图:docs/project/goals.md、docs/project/roadmap.md
- 常见问题:docs/project/faq.md
- 社区参与:CONTRIBUTING.md、CODE_OF_CONDUCT.md
下一步
Carbon 仍处于实验阶段:工具链功能有限、0.1 里程碑未到,但语言设计文档完整、社区迭代快。建议现在就做一件事——构建好工具链后打开 examples/advent2024 挑一天题目,照着common+part1的文件组织方式写一个自己的版本,这是检验今天内容掌握程度的最短路径。
【免费下载链接】carbon-langCarbon Language's main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考