ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Carbon 语言实战:用 Advent of Code 2024 检验实验性工具链的 15 天实例集

Carbon 语言实战:用 Advent of Code 2024 检验实验性工具链的 15 天实例集 Carbon 语言实战用 Advent of Code 2024 检验实验性工具链的 15 天实例集【免费下载链接】carbon-langCarbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang导读本指南以 examples/advent2024/README.md 为核心系统介绍 Carbon Language 主仓库中存放的 Advent of Code 2024AoC 2024示例解题集包括其目录结构、每个题目对应的源码文件组织方式、Bazel 构建规则、共享的输入输出工具库与排序算法实现。读者将掌握如何阅读、构建并运行这些示例理解它们如何作为比工具链自带测试更大规模的真实用例驱动 Carbon 工具链发现缺陷与推进特性开发。一、目录定位这些示例在仓库中的角色在 Carbon Language 仓库的 examples/advent2024 目录下存放着用 Carbon 语言为 Advent of Code 2024 编写的完整解题源码。AoC 是每年 12 月举办的编程竞赛每天发布两个编程谜题Part 1 与 Part 2共 25 天 50 题。该目录共包含1 个说明文档本指南主体README.md1 个 Bazel 构建文件BUILD15 天的解题源码每天一对dayN_common.carbon与dayN_part1.carbon/dayN_part2.carbon共 44 个.carbon文件day1 至 day152 个共享工具库io_utils.carbon输入输出辅助与 sort.carbon泛型快速排序为什么用 AoC 题目做示例Carbon 工具链当前仍处于非常早期的实验阶段官方 README 明确标注NOTE: Carbon Language is experimental。文档原文明确指出这些示例的价值不在展示标准的 Carbon 风格与惯用法——恰恰相反由于工具链功能缺失这些代码经常需要绕开尚未实现的功能代码中大量TODO注释即为证据。它们存在的真实目的是用比工具链自带测试更大的代码规模来检验工具链现状验证编译器在较完整程序上的表现通过运行这些示例发现工具链 bug为开发者提供可复现的最小化真实场景驱动特性开发通过呈现较为真实的测试用例为工具链的功能设计与实现指明方向。这一点与 README 中这些样例需要频繁绕过缺失功能不代表预期的 Carbon 风格和惯用法的声明完全一致——它们是测试工具链的实验载体而非教学示例。二、目录结构与文件组织每天题目的源码按以下约定组织文件模式内容dayN_common.carbon第 N 天两个 Part 共享的逻辑输入解析、公共数据结构、通用函数dayN_part1.carbon第 N 天第一个谜题的入口fn Run()dayN_part2.carbon第 N 天第二个谜题的入口fn Run()io_utils.carbon共享的字符级输入输出工具库sort.carbon泛型快速排序工具库每个dayN_partX.carbon文件都通过library dayN_common语句导入对应的公共文件。以第 1 天为例day1_part1.carbon 开头为import Core library io; import library day1_common; import library sort;可见 Carbon 使用import library ...语句完成库间导入使用import Core library io导入标准库。示例源码内部结构每个解题文件顶层定义fn Run()作为执行入口。例如第 1 天计算两列数字的绝对差之和的完整实现fn Run() { var a: array(i32, 1000); var b: array(i32, 1000); let n: i32 ReadInputs(ref a, ref b); Quicksort(ref a, 0, n); Quicksort(ref b, 0, n); var difference: i32 0; for (i: i32 in Core.Range(n)) { difference Abs(a[i] - b[i]); } Core.Print(difference); }Part 2 则基于同一份排序后的数组用双指针while循环统计相似度得分day1_part2.carbon。从第 12 天开始解题规模显著增大——day12_part1.carbon 直接处理140 × 140的网格用DisjointSetForest并查集计算区域面积与周长这正体现了 README 所述比工具链自身测试更大的代码示例的定位。三、构建系统BUILD 文件如何自动生成二进制目录中的 BUILD 使用 Bazel 的 Starlark 语法将每个day*_part*.carbon源文件自动生成一个可执行二进制目标。其核心逻辑load(//bazel/carbon_rules:defs.bzl, carbon_binary) utils [ io_utils.carbon, sort.carbon, ] excluded [] [ carbon_binary( name carbon_file.removesuffix(.carbon), srcs [ carbon_file, carbon_file.rsplit(_, 1)[0] _common.carbon, ] utils, ) for carbon_file in glob([day*_part*.carbon]) if carbon_file not in excluded ]这段构建逻辑包含三个关键机制列表推导式批量生成目标对glob([day*_part*.carbon])匹配到的每个文件动态生成一个carbon_binary规则。name通过removesuffix(.carbon)去掉扩展名因此day1_part1.carbon生成的二进制名为day1_part1。自动关联公共文件carbon_file.rsplit(_, 1)[0] _common.carbon从day1_part1.carbon推导出day1_common.carbon自动把 Part 文件与其公共文件打包进同一个目标。共享工具库统一注入每个目标都会附加io_utils.carbon与sort.carbon两个工具文件。carbon_binary规则定义于 bazel/carbon_rules/defs.bzl是 Carbon 项目自定义的 Bazel 规则。维护约定构建中断时的处理流程README 给出了明确的维护约定如果工具链变更导致某个示例无法构建处理流程为确认构建失败是该变更的预期后果而非意外回归更新BUILD文件将对应示例加入排除列表。BUILD 文件顶部注释给出了示例语法excluded [day3_part2.carbon]——默认值为[]即所有示例默认参与构建提交 issue 并指派给 zygoloidCarbon 语言技术负责人也是该仓库的核心维护者。从源码看if carbon_file not in excluded这一过滤条件正是为这条维护流程预留的开关当某个示例因预期变更而失效时可先将其排除在构建之外再通过 issue 跟踪修复。四、共享工具库源码解析io_utils 与 sort4.1 io_utils字符级输入输出io_utils.carbon 封装了竞赛解题最核心的 I/O 需求逐字符读取、整型解析与打印。其设计充分体现了工具链早期状态下如何用现有特性拼出完整功能的绕行智慧。CharOrEOF 类型用adapt i32适配底层整数将 EOF 编码为-1README 注释明确EOF 在排序上小于所有char并通过泛型 impl 实现与char的隐式转换、相等比较与有序比较class CharOrEOF { adapt i32; fn EOF() - Self; } impl forall [U: Core.ImplicitAs(char)] U as Core.ImplicitAs(CharOrEOF) { ... } impl forall [U: Core.ImplicitAs(CharOrEOF)] CharOrEOF as Core.EqWith(U) { ... } impl forall [U: Core.ImplicitAs(CharOrEOF)] CharOrEOF as Core.OrderedWith(U) { ... }带回溯的读取原语基于全局var unread_char: Core.Optional(CharOrEOF)实现ReadChar/UnreadChar/PeekChar/ConsumeChar四件套构成简易字符流抽象。泛型整型解析与输出ReadIntN: Core.IntLiteral)以引用参数解析带符号整数PrintInt/PrintIntNoNewline通过pow10逐位分离数字并借助Core.PrintChar输出。这两个函数都通过[N: Core.IntLiteral]泛型约束适配任意精度的Core.Int(N)类型。空白处理SkipSpaces、SkipNewline自动吞掉可选的\r、SkipNChars简化行格式解析。4.2 sort泛型快速排序sort.carbon 演示了 Carbon 泛型编程的一个完整闭环自定义interface Ordered声明Less、LessOrEquivalent、Greater、GreaterOrEquivalent四个比较方法注释中保留了扩展时本应require impls Core.OrderedWith(Self)的设计意图作为待实现特性的 TODOimpl i32 as Ordered为i32提供该接口的实现Swap/Partition/Quicksort三个函数均带约束[T: Core.Copy Core.Destroy Ordered]将类型参数限定为可拷贝、可销毁、可排序同时用[N: Core.IntLiteral]泛型化数组长度。由于接口方法调用语法尚不完善源码中通过a[from].(Ordered.LessOrEquivalent)(pivot)这种显式限定名调用来绕过TODO: if (a[from] pivot)的缺失功能。五、从源码看工具链的早期状态阅读这 44 个解题文件可以直观感受到 Carbon 工具链功能未完备但可用的现状。这类TODO注释遍布源码例如 io_utils.carbon 中// TODO: p 0; crashes the toolchain, see // https://github.com/carbon-language/carbon-lang/issues/6500. p (0 as i32) as Core.Int(N); // TODO: p * 10; crashes the toolchain. p * (10 as i32) as Core.Int(N);从中可以推断出当时工具链的几个已知短板以仓库源码注释为据部分赋值/复合赋值语句会触发崩溃如p 0、p * 10需借助显式类型转换绕行match语句尚未可用条件分支只能退化为if / else if链见 day15_common.carbon 中Square.Make的// TODO: Use matchchar的直接比较与算术不完善需要先转换为u8或i32再运算如(self as u8) (other as u8)Core.ReadChar返回i32与Core.EOF()的比较需显式处理。这些注释中的 issue 链接如 #6500与指派给维护者的约定正是 README 所述用这些例子发现工具链 bug、驱动特性开发的直接证据。六、如何构建与运行这些示例Carbon 使用 Bazel 作为构建系统仓库根目录的 MODULE.bazel 与 BUILD 定义了整个工程示例同样通过 Bazel 构建。构建单个题目bazel build //examples/advent2024:day1_part1Bazel 会依据 BUILD 中生成的规则自动把day1_part1.carbon、day1_common.carbon、io_utils.carbon、sort.carbon编译链接为可执行文件。运行并输入测试数据bazel run //examples/advent2024:day1_part1 input.txt示例程序从标准输入读取 AoC 提供的题目数据每行一对数字输出答案。仓库内的examples/bazel_test_runner.py与testing/目录展示了 Carbon 项目对 Bazel 测试与运行流程的进一步封装可作为参考。验证编译状态bazel build //examples/advent2024:all构建全部 29 个二进制目标15 天 × 2 part其中 day13/day14 的 part2 因文件结构不同按 BUILD 规则自动处理。若某目标构建失败应按照 README 约定的维护流程处理确认是预期变更 → 加入excluded列表 → 提交 issue 指派给 zygoloid。七、这些示例的技术价值总结价值维度具体体现工具链压力测试44 个完整程序、含 50×50 网格、140×140 并查集等较大规模输入远超工具链单测规模缺陷发现载体源码中大量TODO ... crashes the toolchain注释即已发现问题的现场记录特性开发驱动match、char比较、复合赋值等未实现特性的需求均通过注释与 issue 显式登记泛型实践样本sort.carbon展示了interfaceimplforall约束 IntLiteral编译期常量的组合用法维护流程示范excluded排除机制 issue 指派约定定义了工具链变更时示例集的演进规则结语examples/advent2024是 Carbon 项目用真实问题检验真实工具链理念的落地实践它不是教科书式的风格示例而是一组刻意保持较真的完整程序持续为尚在早期的 Carbon 编译器提供超越单元测试的验收场景。阅读这套源码既能了解 AoC 2024 前 15 天的经典算法在 Carbon 中的写法也能一窥当前工具链的能力边界与发展方向。建议感兴趣的读者从 day1_part1.carbon 入手通读再对比 io_utils.carbon 与 sort.carbon 两个工具库即可快速建立对 Carbon 当前语法与泛型系统的直观认识。【免费下载链接】carbon-langCarbon Languages 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),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进