用一周时间学一门新语言

作者:早睡失败者 发布时间: 2026-04-06 阅读量:57 评论数:0

今年三月我给自己放了一周假,目标是学 Rust 到能写出一个能用的小工具。我每天记了流水账,这篇基本是把日记整理了一下,包括所有丢人的部分。

Day 1:一整天在跟编译器吵架

上午看官方教程前四章,感觉良好,觉得不过如此。下午动手写第一个真实一点的东西——一个统计目录下文件行数的小程序,然后就崩了。

我卡了两个半小时在一个函数签名上。我想写一个函数返回目录里的文件名列表,写了七八种签名,编译器每次都给我不同的错误。最后我妥协了,用了最笨的方式:全部 clone 一遍,到处 to_string()

当天的日记我写了一句:「我今天写了 60 行代码,编译成功了 3 次。」

Day 2:放弃对抗,先跑起来

第二天我调整了策略。我不再追求写「地道」的代码,只追求能跑。规则是:凡是编译器不高兴的地方,全部用最暴力的方式绕过去,然后写个注释标记回头再看。

这一天效率高多了,工具的主体功能跑通了。代码里有 14 个 clone() 和 5 个 unwrap(),丑得要命,但它工作。

这个策略后来被证明是整周最关键的决定。先建立正反馈,再追求质量。第一天我如果继续硬啃,很可能第三天就放弃了。

Day 3:读别人的代码

我找了一个我常用的命令行工具,代码量大概八千行,开始逐个文件读。

这一天的收获超出预期。我在教程里死活理解不了的 &strString 的区别,在真实代码里看了二十几个用例之后,忽然就懂了——不是概念上懂,是「什么时候该用哪个」的手感。

我还发现了一个我完全没想到的模式:那个项目几乎所有的错误处理都用了同一套自定义错误类型,而且用了一个宏来生成转换。我照着抄了一份到我的工具里,我那 5 个 unwrap 全清掉了。

Day 4:撞上真正的墙

我想给工具加并发,于是撞上了整周最大的墙。

我要在多个线程之间共享一个计数器。凭直觉写出来的代码编译不过,试了 ArcMutexRwLock 各种组合,报错信息我读了三遍还是不懂。

下午四点,我做了一件事:合上电脑,拿纸笔画。画谁拥有这块内存、谁借用它、生命周期到哪结束。画了大概四十分钟,忽然通了。

那一刻我意识到,前三天我一直在用别的语言的心智模型去套 Rust。我以为变量是「名字指向值」,但在这里,变量是「谁负责这块内存的生死」。这个转换一旦发生,之前所有莫名其妙的报错都变得合理了。

Day 5:重写

把 Day 2 的丑代码重写了一遍。14 个 clone 减到 3 个。运行时间从 4.2 秒降到 1.1 秒——大部分不是因为少了 clone,是因为我顺手改对了一个 IO 模式。

这一天最爽的是,我开始能预测编译器会不会报错了。这是熟练度的第一个信号。

Day 6:踩生态的坑

我想加个配置文件解析,选了一个流行的库。文档看着简单,实际用起来发现版本对不上——我在网上搜到的示例代码是老版本的 API,新版本改了签名。

这个坑花了我一个半小时。教训是学新语言时搜到的答案有很高比例是过期的,一定要先看当前版本的官方文档。我后来养成习惯,先在本地生成一份文档,只查本地的。

Day 7:收尾和评估

最后一天我把工具打磨了一下,写了 12 个测试,发布了。总共 640 行代码。

然后我做了一次诚实的自我评估:

  • 能读懂中等复杂度的代码:基本可以
  • 能独立写出小工具:可以,但慢
  • 能设计一个模块的类型结构:不行
  • 知道什么是地道写法:完全不行
  • 能在生产项目里用:绝对不行

一周之后我总结的方法

这套流程我后来用在别的语言上也管用:

  1. 第一天允许自己写丑代码。目标是跑通,不是优雅。
  2. 第三天必须读真实项目。教程给概念,真实代码给手感,两者不可替代。
  3. 遇到反复不理解的东西,离开键盘。那通常意味着心智模型错了,而不是知识点没记住。用纸笔画。
  4. 最后一天必须做诚实评估。不要骗自己「我会 Rust 了」。「我能用 Rust 写小工具」和「我会 Rust」差了两年。

顺带一提,那个工具我到现在还在用,五个月了没改过。它做的事很简单,但它是我的。这大概是学一门新语言最好的纪念品。

评论