# 编程语言内容编写与维护规范
适用于 docs/languages/ 中的导航、实作文章和设计分析。目标是让读者能定位差异、复现示例、理解适用边界,而不是把八种语法机械排列。目录组织与全库维护要求仍遵循仓库维护规范。
本文件是本主题的统一流程入口;模板只提示文章结构,验证记录保存执行证据,现状审查保存问题与整改条件,不另建重复规则。下文“必须”是准入条件,“建议”允许说明理由后选择其他做法。既有文章按风险和实际修改逐步复核,不因新增规范自动获得通过状态。
# 维护流程
按下表推进一个选题或一组紧密相关的修订,不以“正文已生成”代替交付。编写者负责契约和示例,复核者检查论据与反例,整合者负责最终运行证据、导航和页面;同一人可承担多个角色,但不能省略检查环节。
| 阶段 | 必须产出 | 进入下一阶段的条件 |
|---|---|---|
| 1. 定位与定界 | 查阅本章目录和相邻文章,确定复用或新增;列出目标读者、问题契约、非目标、语言范围 | 不重复已有主题;跨语言共同输入域和预期行为明确 |
| 2. 查证与设计 | 列出关键论断及一手来源;先设计正常、边界、失败用例,再选实现机制 | 版本前提明确;语言事实与个人分析分开;数量结论有测量方案 |
| 3. 编写与组装 | 使用相应模板,完成文件名、代码块关系、运行命令、调用方及预期结果 | 从空的隔离目录按正文操作,不需猜测 import、包配置或替换范围 |
| 4. 语义复核与实跑 | 按文章和语言记录实际命令、输入、输出、退出码及未覆盖部分 | 实现满足共同契约;已知错误未被小样例或“渲染成功”掩盖 |
| 5. 整合与发布 | 对齐正文、验证记录、目录和相关分析;渲染并检查实际页面 | 发布清单完成;无互相冲突的状态,无临时协作指令与产物 |
并行或 AI 辅助编写前,整合者先固定共同契约、基线和文件边界。各任务只交付其修改范围与实际执行证据;“已完成”“测试通过”等任务报告必须核对具体输出后才能写入正式记录。最终正文不能出现“待父级统一执行”等内部交接语句,未执行范围应写成面向读者的明确状态。
# 修改触发的复核范围
- 修改输入范围、错误策略、输出或代码:重跑受影响语言的正常、边界和失败路径;共同契约变化时复核所有对照实现。
- 修改基线、依赖或运行命令:重新从隔离目录组装执行;仅在新版通过,不能反推旧基线兼容。
- 修改被设计文章引用的实现:同步检查相关结论,不能继续引用已经失效的保证。
- 修改标题、文件名或路径:更新入链、目录和阅读路径,检查生成 HTML 的实际锚点。
- 仅改措辞或排版且不改变含义:可不重跑代码,但仍检查受影响链接和页面,并说明沿用哪条执行记录。
存在错误结果、不可复现入口或与实现矛盾的结论时,必须先修复或明确标记受影响范围,再把文章列为已复核内容。已知问题尚未解决时保留在问题单中;不能通过删除失败用例、静默缩小契约或扩大未测试的通过声明来关闭问题。
# 选题与阅读路径
- 一篇解决一个明确问题;先定义输入、输出、失败和不处理的范围,再选择语言与机制。
- 保留九个主题目录。总览分别展示“当前可读路径”和“完整主题大纲”,计划条目不创建空链接或占位正文。
- 基础主题覆盖八种语言;专有机制按价值选择语言并解释取舍,不强求等价调用形状。
- 正文开头用一两句说明学习目标,列出真正影响理解的前置知识。使用后续章节的概念时,说明本篇需要理解到什么程度,不依赖尚未发布的文章才能运行代码。
- 链接文字采用稳定短标题,例如“字符串转端口号”;正文一级标题可以附带解释性副标题。
- 渲染器根据目录结构生成面包屑和侧栏,并按编号章节、章内目录顺序生成上一篇、下一篇;
scripts/navigation.json中的精选导读作为独立跳读入口。正文不手写这些导航;前置关系和应用场景通过相关阅读说明,不能仅凭顺读顺序推断。
# 结构与排版
实作文章使用实作模板,设计论证使用设计分析模板。删除不适用的栏目,不为形式制造重复总结。
- 每篇只有一个一级标题;不跳级。实作的各语言置于二级“各语言实现”下,使用三级语言标题。
- 篇内目录由渲染器根据二、三级标题与实际锚点生成;各语言、关键差异和验证说明应使用相应标题,正文不手写目录链接。
- 关键差异置于实现之前,帮助读者带着问题阅读。表格只容纳比较维度、短语和短表达式;完整函数使用带语言标识的围栏代码块。
- 对比信息只集中呈现一次。代码后的文字解释“为什么这样写”和“与其他语言哪里不同”,不逐行翻译显而易见的代码。
- 长条件和调用按语言惯例断行;不要为了窄屏破坏代码语义,也不要把主实现默认折叠。发布前检查桌面和窄屏页面。
- 官方引用就近放在受支持的论断后。文末“延伸阅读”只放补充资料,不再复制全部行内链接。
# 篇内锚点
本仓库 HTML 渲染器为每个标题生成 id:取可见文本,英文转小写,保留 Unicode 字母、组合标记、数字、空白、下划线和连字符,删除其余标点与符号,去除首尾空白,连续空白替换为一个连字符。
例如,各语言实现 对应 #各语言实现,Rust 对应 #rust,C++ 对应 #c。空结果使用 section。同页出现冲突时追加 -1、-2 等,直到唯一;不同页面独立计数。
正文优先使用简单、唯一的标题,避免依赖去重后缀。其他 Markdown 平台的锚点算法可能不同;标题改名后必须检查指向该节的链接,并在实际 HTML 中验证跳转。
# 问题契约与公平比较
- 区分输入类型、文本格式、数值范围和业务约束。例如“字符串能转整数”不等于“符合端口配置协议”。
- 成功案例给出具体返回值或精确输出;失败案例说明返回错误、抛异常或其他可观察行为,不能只写“处理异常”。
- 覆盖边界和容易误迁移的输入。范围判断包含边界内、边界上、边界外;避免仅用中间值证明正确性。
- 不偷偷改变语言之间的前置条件。若一个实现接收字节、另一个接收文本,必须解释编码及比较范围。
- 不把一种实现方式说成语言唯一能力。区分静态约束、运行时检查、工具诊断和调用方约定。
- 简化机制时标明限制;不要把行数、是否有异常、是否使用继承直接等同于优劣。
- 算术题必须说明输入和中间结果的范围、溢出或精度策略;“正整数”不是有限位宽和安全整数范围的替代。即使输入都可精确表示,也要检查运算结果。
- 文本题明确空串、空白、换行、Unicode 与编码边界;状态题明确合法转换及失败后状态。只验证与本题契约有关的边界,不扩展无关功能。
- 并发题区分“发出取消”“停止等待”“任务退出”和“资源清理完成”;用可观察状态或同步机制证明完成,不用睡眠时长或打印顺序替代证明。
# 代码与运行说明
# 完整程序和片段
完整程序不重复添加“完整程序,保存为……”和常规编译、运行命令。函数片段、驱动片段或替换片段须明确标注,必要时给出文件名。片段必须写明与哪些块组合、按什么顺序组合、哪些内容替换而不是追加。
- 完整程序说明必要依赖与预期输出;仅在涉及特殊参数、模块配置或其他非默认条件时补充运行说明;没有控制台输出但包含断言的程序,也要说明成功表现。
- 函数片段必须提供明确调用入口。不要只写“添加 main 后调用”,也不要让读者自行猜测 import、类作用域或文件名。
- 介绍失败机制时同时展示调用方:何时可使用返回值、失败在哪里分支、由哪一层向用户报告。不能吞掉错误或静默使用默认值,除非这正是明确的业务契约。
- JS/TS 共享运行时逻辑时,共享解释;各语言主示例保留完整程序,不要求读者跨小节拼装函数签名、函数体和调用入口。类型标注不是运行时输入校验。
- 示例默认标准库。第三方库说明目的、版本和安装条件,不为短例子引入工厂、适配层或自定义协议。
- 每个新增检查都应有契约或教学理由。前置检查已排除的解析失败,不应再被描述为本例实际会触发的分支。
- 文件示例使用临时目录等隔离位置,不覆盖读者已有文件;明确编码、换行、资源释放和清理失败的归属。
- 运行命令涉及操作系统差异时标明差异,例如可执行文件在 PowerShell 下用
.\main.exe,在 POSIX shell 下用./main。 - 每种语言使用独立的临时工作目录;TypeScript 生成的
main.js不得覆盖手写 JavaScript。Node.js 必须明确 CommonJS 或 ESM、文件扩展名与包配置,不能依赖仓库的package.json恰好生效或运行时自动猜测。 - 自检优先使用标准断言或简单的显式检查,不为每篇复制一套通用断言库。Node.js 可使用
node:assert/strict;TypeScript 若引用 Node 类型,必须交代类型依赖和安装条件,不能为统一外观隐含新依赖。 - 使用 Java
assert时命令必须包含-ea;Python 不使用-O,C++ 不定义NDEBUG来执行依赖断言的验证。也可使用不受开关影响的显式检查。异常用例必须在未抛出时失败,且非预期异常不能被吞掉。 - 类型错误反例单独标明为“预期编译失败”,记录失败命令和关键诊断;不能与应成功的完整程序混在一起,再宣称整篇编译通过。
# 从机制到设计分析
设计分析必须引用已有实现,并选定一个真实变化,例如增加文件目标、调整合法输入范围或新增失败原因。依次回答:
- 哪些代码需要修改,哪些保持不变?
- 类型系统或工具能检查什么,何时反馈?
- 哪些语义只能由运行验证和接口约定保证?
- 调用方还承担什么责任,失败如何传播?
- 抽象收益是否值得声明、阅读、运行或维护成本?
不把“失败在返回类型中”写成“调用方必然正确处理失败”,也不把垃圾回收写成文件和连接及时释放的保证。
# 版本与来源
- 语言基线统一引用主题首页,只有文章有额外条件时才单独注明。
- 基线不是最新版本声明,也不是经过测试的最低版本。实际工具链和验证日期记录在验证记录。
- 优先官方文档、规范和原始设计资料。引用链接应支持紧邻论断;例如
typing.Protocol的依据应指向类型协议资料,而不只是io模块首页。 - C++ 工作草案和不带版本号的在线文档可能持续更新。引用时说明该限制,不把当前草案当成 C++17 等历史基线的兼容证明。
- 分清可核验事实、基于示例的分析和待核验内容;无法执行或确认的事项明确记录,不猜测通过状态。
- 将语言规则、标准库承诺、具体编译器/运行时行为、生态观察分开。不能把某次分配、静态链接配置或一段代码的表现上升为整门语言的保证;未定义行为不能表述为必然崩溃。
- 性能、内存、镜像大小和启动时间等数字必须附测试程序、版本、平台、构建选项、测量方法和日期;没有这些依据时,不给出貌似普适的数值区间。生态趋势和团队效率判断也必须有范围、来源或明确标为观点。
- 维护基线时,除语法级别外还要写明实际依赖的运行时或标准库能力。Rust edition 不是编译器版本,ES2022 不是 Node.js API 版本;新增 API 的可用性必须另行核对。
# 验证证据与状态
内容完成度与执行状态分开管理。章节目录仅展示主题与比较重点,不展示完成状态;文章存在不代表已复核或运行通过。执行状态以验证记录中可定位到文章和语言的条目为准,正文链接到具体记录,不另写一份易失步的通过矩阵。
| 状态 | 含义与所需证据 |
|---|---|
| 未执行 | 只有预期行为或阅读核对;写明缺少的工具链、环境或尚未覆盖范围 |
| 部分验证 | 只有部分语言、代码块或场景执行过;逐项列出通过和未执行部分 |
| 通过 | 指定文章版本、语言和用例集满足预期;不代表全篇所有语言或全部基线通过 |
| 失败 | 保留实际与预期差异、复现步骤和影响范围;不得仅记“待优化” |
| 待复核 | 历史证据不足、记录冲突或相关代码已改变;旧结果保留历史身份 |
| 不适用 | 纯分析等无独立可执行内容;仍须做来源与推理复核,不能称为运行通过 |
每条执行记录至少包含:
- 对象:文章相对链接、语言小节、块类型及组装方法;代码版本使用提交号或文档/代码 SHA-256,注明哈希对象。未提交的修改不能仅以旧提交号标识。
- 环境:核验日期、操作系统、实际编译器/运行时版本、影响结果的参数与依赖;基线版本另列,不混作实测版本。
- 步骤:隔离目录要求、文件名、原样执行命令、输入及用例范围;额外驱动或替换步骤必须足够复现。
- 结果:预期与实际输出、退出码、断言或关键诊断;无输出时也要说明检查了什么。临时日志可不提交,但摘要必须保留可观察结果,不能只写“通过”。
- 边界:未执行的语言、失败注入、平台和场景;CLI 的无参数演示与带参数调用分别计入覆盖。
验证记录按日期追加,历史摘要不冒充当前全库状态。若同一对象出现“通过”和“未执行”冲突,先标记待复核,定位代码版本和用例后再定状态;不凭较新的日期猜测谁正确。修复后保留原反例及新结果,只有对应范围获得通过结论。
文档验证与示例验证分别记录。当前 package.json 只有 build、render 两个脚本,均调用渲染器,没有仓库级 Markdown 检查或多语言测试命令。已有依赖时执行 npm run render;首次或锁文件变化时先执行 npm ci。链接检查应覆盖目标文件和生成 HTML 的标题 ID;人工或临时脚本检查都必须记录范围,不能把渲染成功等同于链接和示例全部正确。
# 发布前检查
- [ ] 输入、成功、失败和非目标清楚,各语言契约一致。
- [ ] 核心对照、语言解释与设计结论相互支撑,没有把教学选择写成语言限制。
- [ ] 按文章说明组装并运行新增或修改示例,检查成功、失败及相关边界。
- [ ] 验证条目可定位到文章、语言、代码版本和用例;实际结果与预期分开,旧记录及未覆盖部分没有被总括为通过。
- [ ] 一个一级标题,标题不跳级,代码围栏完整且标明语言。
- [ ] 文件链接和章节锚点有效;新增文章已出现在生成的目录中;需要自定义排序、说明或导读顺序时已更新
scripts/navigation.json。 - [ ] 从仓库根目录执行
npm run render,打开输出页面,实际点击篇内和跨篇链接,检查窄屏的表格与代码。 - [ ] 模板说明已替换为真实正文,无未填写栏目、临时文件、编译产物或敏感内容。
- [ ] 关键事实有就近来源;性能与生态结论有适用条件,无无依据的量化排名。
- [ ] 正文、验证记录、目录状态一致;受影响的实现和设计分析已复核,遗留问题没有被宣称为已解决。
渲染只验证文档能够生成页面,不证明代码示例正确;示例运行通过也不等于所有声明的基线版本均已测试。