我教了十年编程,最常听到学生问我一个问题。“老师,我到底该怎么看源码?” 问这个问题的人,往往已经学完了基础语法,能写简单的项目。他们卡在一个地方,就是不知道下一步该往哪走。有人告诉他们说,看源码是进阶的最快方式。这话没错,但大多数人打开一个开源项目,看到几十上百个文件,直接就蒙了。
你肯定遇到过这种情况。点开一个项目的GitHub页面,第一反应是恐惧。目录里那么多文件夹,每个文件夹里还有好几层文件。你心想,这得看到什么时候去。有的人硬着头皮从头看到尾,看着看着就睡着了。有的人只挑开头几个文件看,感觉什么都没看懂。最后得出一个结论,这玩意不适合我看。
真相是什么?真相是你用错了方法。阅读源码不是读小说,不需要从头翻到尾。阅读源码更像是在解剖一只鸡,你得知道该从哪个部位下刀。如果你不知道目标就去看源码,那你就是在大海里捞针。
我现在告诉你一个最直白的策略。你找一个你正在用的小框架或者小工具。注意,一定要是小的,别一上来就搞React或者Vue。找一个你熟悉的工具,比如一个HTTP请求库,或者一个模板引擎。你用过它,知道它干什么用。接下来你需要搞清楚一件事,你只关注一个动作,就是它如何接收输入,又如何吐出输出。其他所有无关的代码,统统不看。
具体怎么做。你先去跑一个最简单的例子。用这个库写一个最小功能,比如发一个GET请求。然后你打开它的测试文件。对,测试文件是你看源码的最佳入口。测试文件会把库的各种用法写得很清楚。你看测试代码,对照着官方文档,大概就能猜出每个参数是干什么的。
看完测试还不够。你去找一个叫“入口文件”的东西。大多数库都会有一个index.js或者主模块文件。打开它,你看到的第一行函数或者变量,往往就是核心逻辑。你把这个核心函数找到,然后开始看它调用了哪些子函数。这样一层层往下挖。你不需要把每个函数每行代码都弄明白,你只需要搞懂它实现一个功能的逻辑链条。
我打个比方。你看到源码里有这样一段代码,一个函数叫sendRequest,它里面调用了createHttpBody,又调用了openConnection。你不需要现在就去搞清楚createHttpBody是怎么拼接字符串的。你只需要知道,这个库发请求的流程是先创建请求体,再打开连接。这就算你弄明白了。能画出这个流程图,你的第一步就读完了。
第二天,你再深入一点。去看createHttpBody这个函数,它具体是怎么做的。这个时候你会发现,它可能处理了不同请求头,或者处理了参数编码。你一点一点地啃,每次只看一个函数。一周时间,你就能把一个几百行的小库啃得七七八八。
很多人失败,是因为他们贪多。他们打开一个库,想一口气把所有功能都搞明白。你别这样。给自己定一个小目标,我就搞清楚这10行代码是干什么的。搞清楚了就奖励自己休息一下。看源码这个事,就像拼积木,你得一块一块拼,不能指望着看一眼就拼完整座城堡。
还有一个技巧。你拿到一个不懂的函数或者变量,别去翻文档。直接在代码里搜索它是哪里定义的。很多编辑器都有“转到定义”的功能。你点一下,就能跳到它声明的地方。这个方法比查文档快十倍。源码本身就是最好的文档。
最后我想说一句,你不是能力不够,你是方法不对。那些能看源码的人,不是比你聪明,是他们知道该从哪个角度看。你只需要迈出第一步,哪怕只看懂了一个函数的实现,你都迈出了一大步。把那扇门打开,哪怕只推开一条缝,光就会透进来。你试试看,今天就开始,找一个你熟悉的小工具,打开它的测试文件,给自己一个理由去看懂它。你行。
夜雨聆风