上周整理老房子储物间,翻出父亲那台2019年的ThinkPad,键盘W键磨得发白,D盘根目录下堆的全是当年给社区食堂和面机写的控制程序备份。外壳上还贴着2020年南京马拉松的纪念贴纸,边角已经卷起来了。
总出故障的老程序
父亲在老下关做了快三十年工控,之前给附近的小厂子、社区食堂、甚至街道的自动喷灌系统写控制逻辑,用的全是C。2022年夏天那事他记到现在。那天社区食堂的和面机揉面揉到一半突然停机,温控模块还跳了高温报警,厨师长打了三个电话催他过去。他蹲在工控柜旁边拆了半小时,最后发现是当年写的程序里有个内存越界、野指针问题,把温控的参数给覆盖了。
说实话,这种坑在C程序里太常见了。他踩了不下几百次,每次都是打个补丁就完事,从来不敢大改——毕竟那堆一千多行的代码堆在一个文件里,改一个地方,说不定别的地方直接跑飞。那天他蹲在机器旁边抽了半包红南京,烟蒂扔在脚边,烟灰飘到工控柜的散热孔里,他还赶紧用手指抠出来。

他说这破程序迟早要炸,但是改不动了。之前每次修都要花大半天,有时候修完过两个星期又出别的毛病,厨师长虽然没说啥,但是他自己觉得不好意思,毕竟是自己写的东西。
被按头试的新工具
我之前在互联网公司做了几年后端,2021年开始摸Rust,之前跟父亲提过好几次,他都嫌这东西太新,社区里没几个人用,出问题找不到人问,死活不愿意碰。那次故障之后,他蹲在食堂门口坐了半小时,给我打了个电话,说“你上次说的那个什么Rust,你过来帮我弄弄?”
我抱着电脑过去的时候,他已经把老ThinkPad的电源都插好了,老花镜放在键盘旁边。我帮他装Rust工具链,老电脑网速慢,等了二十分钟才装完。然后把原来堆在一个文件里的一千多行C代码拆成了和面参数、温控模块、故障报警三个独立的crate,每一块的逻辑都写了简单的注释,连之前他藏在代码角落里的那个“夏天温度超过35度就自动降速”的小彩蛋都单独拎出来做成了可配置项。
第一次跑cargo build –release的时候,终端滚完最后一行,蹦出来个无关紧要的warning,父亲凑过来,老花镜滑到鼻尖,说“这就完了?没有报什么内存错误?”
我当时笑到手里的矿泉水都洒了,之前他用gcc编译,每次都要蹦出来好几个“隐式声明”“指针类型不匹配”的警告,他每次都要对着警告改半天,有时候改完还跑飞。

他把那个编译好的程序拷到工控机上,跑了一整个星期,和面机连一次自动停机都没有。之前每天至少要出两三次小毛病,那一周连报警灯都没亮过。他后来跟我说,那天晚上他在食堂门口坐了好久,风刮过来,闻着里面飘出来的面粉香,觉得这东西好像真的有点用。
其实Rust最核心的就是所有权系统,不用手动管内存,编译器会帮你把所有可能出现的内存问题都拦在编译阶段,不会等到跑起来的时候才炸。而且它的零成本抽象意味着写出来的程序性能跟C差不多,完全满足工控系统对实时性的要求——毕竟和面机的温控要是慢个几毫秒,说不定就把面发过了。
慢慢变了的工作习惯
不过话说回来,父亲一开始也不是完全信任这东西。他把原来的C程序备份了三个地方,U盘、老电脑、还有他那个写满笔记的硬皮本,就怕新程序出问题,还能赶紧切回去。结果跑了半个月,一点问题都没有,他才敢把原来的备份给删了。
上次我回家,看见他在那个硬皮本上画Rust的所有权转移示意图,画得歪歪扭扭的,旁边还印了个红南京的烟圈印子。之前他改程序都是先改了再说,出问题再补,现在居然会先写几个简单的测试用例,比如模拟温度超过35度的时候,机器会不会自动降速,模拟和面时间到了会不会自动停机。
他现在接活,都先问人家能不能用Rust写。说“写一次能用五六年,不用天天跑过去补补丁”。之前他每个月要跑社区食堂三四次,现在两个月才去一次,去了也是帮人家换个面粉筛子,跟厨师长聊聊天。上次老同行找他改街道的喷灌系统,说“你现在怎么用这么偏门的东西?万一你哪天不在了,我们找谁修?”
父亲把那个硬皮本推到他面前,说“我把代码都注释好了,每个模块写了啥,都记在这上面,你们要是真要改,找个会Rust的小孩,半天就能看懂,比之前那堆堆得像屎山的C代码强多了。”
上周整理那个旧笔记本,翻到最后一页,父亲写了一行字,歪歪扭扭的:“原来写程序不用天天跟内存打架。”
昨天他给我发微信,说给小区门口的自动取快递柜写了个小的监控程序,用Rust写的,跑了三个星期,没出过一次错。他还说,下周要跟社区里的几个老工控师傅开个小茶会,讲讲这个东西怎么用。
我看着那条微信,突然想起之前他蹲在和面机旁边抽烟的样子,烟灰掉在散热孔里,他还赶紧用手指抠出来。好像也没过去多久。
我没问他以后会不会彻底放弃C,就像我没问他第一次看见编译成功的输出时,心里到底在想什么。有些选择本来就不需要什么宏大的理由,只是少跑几趟路,少抽半包烟,就够了。
作者|大讲堂
排版|大讲堂
审核|乐乐
大讲堂