第 59 章 让 IDE 和 AI 替你动手
本章写于 2026 年 10 月。工具更新很快,具体的菜单名、快捷键和产品能力以你手里的版本为准;本章讲的做法不会过时。
前面每一章的“怎么一步步做”里都标了”(IDE 可自动完成)“。这一章把这些能力汇总起来,再讲两类帮你发现问题的工具(代码检查和类型检查),最后讲怎么让 AI 编程助手替你做重构,以及哪些事不能交给它。
IDE 能自动做的重构
Section titled “IDE 能自动做的重构”自动重构和手工改有本质区别:IDE 是按语法和符号理解代码的,它知道 name 这个词在这一行是变量、在那一行是字符串里的普通文字。所以它改名时不会误改字符串和注释,提炼函数时会自动分析哪些变量要变成参数、哪些要变成返回值。能用自动重构的地方就别手工改,它比你细心。
下表是三个常用编辑器在 Windows 和 Linux 默认键位下的入口。macOS 上把 Ctrl 换成 Cmd、Alt 换成 Option,个别快捷键不同,以菜单里显示的为准。
| 手法 | 章 | VS Code | PyCharm / WebStorm |
|---|---|---|---|
| 变量改名、函数改名、字段改名 | 6、7、31 | F2 | Shift+F6 |
| 提炼函数 | 4 | 选中代码,Ctrl+. 选 Extract function | Ctrl+Alt+M |
| 提炼变量 | 5 | 选中表达式,Ctrl+. 选 Extract constant 或 variable | Ctrl+Alt+V |
| 内联函数、内联变量 | 4、5 | Ctrl+. 选 Inline(TS 支持较好,Python 视扩展而定) | Ctrl+Alt+N |
| 改变函数声明(增删参数、调整顺序) | 6 | 无内置,靠改名加手工修改 | Ctrl+F6 |
| 搬移到另一个文件 | 21 | Ctrl+. 选 Move to a new file / Move to file(TS) | F6 |
| 所有可用重构的总入口 | — | Ctrl+Shift+R | Ctrl+Alt+Shift+T |
几点经验:
- VS Code 的能力取决于语言扩展。 TS 和 JS 由内置的语言服务支持,重构菜单比较完整;Python 取决于安装的扩展(Pylance 等),改名和提炼一般都有,内联和改签名可能缺。
- JetBrains 系列(PyCharm、WebStorm)的重构最全。 改变函数声明会同时更新所有调用方,搬移会自动改导入语句,这两样手工做最容易漏。
- 动态语言的自动重构有盲区。 Python 里通过字符串调用的方法(
getattr(obj, "name"))、TS 里通过方括号访问的属性(obj["name"]),IDE 都找不到。自动改名之后,全文搜一下旧名字。 - 自动重构之后照样跑测试。 它比手工可靠,但不是不会出错,尤其在动态特性多的代码里。
代码检查:帮你闻到坏味道
Section titled “代码检查:帮你闻到坏味道”第 2 章的很多坏味道可以被工具量出来。代码检查工具(linter)跑在编辑器里或提交前,把可疑的地方标出来,相当于一个不知疲倦的评审。
Python 常用 Ruff(它实现了 Flake8 的大部分规则和 Pylint 的一部分规则,速度很快),TS 和 JS 常用 ESLint 加 typescript-eslint。和坏味道对应的规则举例:
| 坏味道 | Ruff 规则 | ESLint 规则 |
|---|---|---|
| 过长函数、复杂条件 | C901(圈复杂度)、PLR0912(分支过多)、PLR0915(语句过多) |
complexity、max-statements、max-depth |
| 过长参数列表 | PLR0913(参数过多) |
max-params |
| 死代码 | F841(未使用的变量)、F401(未使用的导入)、ERA001(被注释掉的代码) |
no-unused-vars、@typescript-eslint/no-unused-vars |
| 重复的条件 | SIM 系列(可简化的写法) |
no-else-return、no-lonely-if |
这些规则给的是阈值,不是判决。圈复杂度超过 10 的函数不一定要拆,但值得看一眼。把规则当成“该去看看了”的提醒,具体怎么改仍然是你的判断。
类型检查:重构的安全网
Section titled “类型检查:重构的安全网”Python 的 mypy 或 Pyright、TS 的 tsc,在重构时是测试之外的第二张安全网。改了一个函数的签名,类型检查会立刻列出所有没跟着改的调用方;把字段搬到另一个类,所有还在旧位置读它的地方都会报错。本书所有 TS 代码都开着 strict 跑过 tsc,就是这个原因。
类型越精确,网越密。第 15 章把优先级从 str 换成 Priority 之后,任何把裸字符串当优先级传的地方都会被类型检查抓住,这是 str 类型做不到的。重构到更精确的类型,本身就让后续的重构更安全。
版本控制:把重构和功能分开
Section titled “版本控制:把重构和功能分开”第 58 章说过,重构和功能改动要分成不同的提交。这件事靠自觉很难坚持,git 本身有几样工具帮得上忙。
按块暂存。 你改着改着,工作区里同时有了重构的改动和功能的改动。git add -p 会把改动按块逐个列出来,问你每一块要不要暂存。先只暂存重构的那几块,提交一次“提炼函数:amount_for”;再暂存剩下的功能改动,提交第二次。大多数编辑器的 git 面板也支持按行或按块暂存,效果一样。
看词级差异。 重构经常是改名和挪位置,行级的差异会显示一整行被删掉又加回来,看不出到底变了什么。git diff --word-diff 只标出变化的词,改名一眼就能看出来;git diff --color-moved 会把整块挪动的代码用另一种颜色标出,评审的人可以跳过它们,把注意力放在真正改动的地方。
小步提交,随时回退。 每完成一个手法就提交一次,提交说明写上手法名。走错了,git reset --hard 丢掉所有未提交的改动,回到上一个提交,最多损失几分钟。想把一串小提交合成一个再推送,可以在推送前整理提交历史,但在本地,提交越碎越安全。
提交前自动检查
Section titled “提交前自动检查”把代码检查、类型检查和测试挂在提交前自动运行,是让这些工具真正起作用的办法:只靠记得手动跑,总有忘的时候。
Python 项目常用 pre-commit 框架,在配置文件里列出要跑的工具(Ruff、mypy),每次 git commit 时自动执行,有问题就拦下这次提交。JS 和 TS 项目常用 husky 配合 lint-staged,只检查这次改到的文件,速度快。持续集成服务器上再跑一遍完整的测试和检查,作为最后一道关。
对重构来说,最重要的是测试要快。一次完整的测试如果要跑十分钟,你就不会每做一步都跑一次,小步重构的节奏就断了。把测试分成快的单元测试和慢的集成测试,重构时只跑和改动相关的快测试,提交前或持续集成时再跑全部。本书的代码示例都是秒级的测试,正是为了让你养成“改一步、跑一次”的习惯。
让 AI 助手重构
Section titled “让 AI 助手重构”到 2026 年,AI 编程助手已经是很多人日常工具的一部分:在终端里工作的 Claude Code,集成在编辑器里的 GitHub Copilot、Cursor 等。它们都能根据一句话描述改写代码,重构是它们最擅长的任务之一,因为重构有明确的目标(行为不变)和明确的检验办法(测试通过)。
用得好,它能替你完成大量机械的改动;用得不好,它会在“顺手改进”中悄悄改变行为。下面是本书推荐的做法,它们和你自己做重构时的原则完全一样。
一次只提一个手法。 说“对 statement 做提炼函数,把计费的 if 链提成 amount_for”,而不是“把这段代码重构得好一点”。前者的结果你可以一眼核对,后者会得到一大片你没要求的改动,评审起来和看别人的大提交一样累。用本书的手法名和它沟通很有效,这些名字它都认识。
先让它写测试。 要重构的代码没有测试时,第一个请求应该是“给这个函数写特征测试,记录它现在的行为,不要修改函数本身”(第 58 章)。跑一遍,确认测试通过,再开始重构。
你来跑测试,你来看改动。 每一步之后自己跑测试、自己看改动的差异,不要只听它说“已经完成,测试通过”。终端里的助手可以替你执行测试命令,但结果要你亲眼看过。
不接受“顺手”的改动。 你要求提炼函数,它却同时改了一个判断条件、换了一个库、加了一段错误处理。即使这些改动看起来是好的,也要求它撤掉,或者单独作为一次改动提出来。重构的价值在于每一步都可以确信行为没变,一旦混进了行为改动,这个确信就没了。
让它解释为什么。 问它“这段代码有什么坏味道,你会用哪个手法,为什么”,比直接让它改更有价值。它的分析不一定对,但会给你一个讨论的起点,你也能借此检验自己的判断。
给它足够的上下文。 助手看不到的东西,它只能猜。告诉它项目用的语言版本和测试命令,指给它相关的文件和调用方,说明哪些接口是对外公开、不能改签名的。终端里的助手可以自己去读代码和跑命令,上下文问题小一些,但关于“哪些不能动”的约束,仍然要你明确说出来。
一个好的请求大致是这样的:先说要做哪个手法、对哪段代码做;再说约束,比如“不要改 statement 的签名,它是公开接口”;最后说怎么验证,比如“改完运行测试命令,把结果给我看”。三句话说清楚,得到的改动通常就能直接评审。
大的重构由你规划,小的步骤交给它。 第 57 章那样的完整重构,先后顺序、在哪里停下来、最终结构长什么样,应该由你决定,因为它取决于你面前的需求,而助手不一定知道那些需求。把计划拆成一个个具体的手法,再一步一步交给它执行。
- 能用 IDE 自动重构就别手工改:改名、提炼、内联、改签名、搬移,它按符号理解代码,比文本替换可靠。
- 代码检查工具能量出很多坏味道,把它的报警当作“该去看看了”,而不是判决。
- 类型检查是测试之外的第二张安全网;类型越精确,重构越安全。
- 让 AI 助手重构时:一次一个手法、先补测试、自己跑测试看改动、拒绝顺手的行为改动、大计划自己定。