把ownership那套直觉搬回C,真正能落地的不是"想清楚",而是把"想清楚"固化成代码层面的约束。编译器在Rust里替你盯的东西,C里得靠命名约定和工具链自己补上。
函数签名直接标ownership最实用。指针传进去是借还是送,用命名区分,比如buf_consume()表示接管所有权、buf_view()表示只读借用,比注释管用,读代码的人不用猜。其实再激进点,送出去的指针用__attribute__((malloc))标注,gcc/clang能帮你做基础的所有权跟踪。
资源释放也能模拟RAII(Resource Acquisition Is Initialization,构造即获取、析构即释放的C++套路)。C没析构,但goto cleanup加单一出口能顶上:每个函数开头把所有资源置NULL,出错统一跳到cleanup按NULL判断释放。这套写顺了,double free和泄漏基本只在写新函数的头十分钟冒出来。
零成本抽象那点补一句:Rust的zero-cost指"不为没用到的抽象付运行期代价",不是"抽象免费"。单态化让二进制膨胀、编译变慢,Rc/RefCell、async状态机都有运行期开销。所以"该抽象就抽象"在C里也要加前提——先profile再决定。我见过有人在热路径为了可读性套一层函数指针间接,cache miss吃掉的远比那点指令多。
你说比防segfault值钱,我同意,但还想补一层:ownership理清之后并发bug也好找。C里的data race本质是同一块内存被两个owner同时写,把Rust的Send/Sync模型在脑子里过一遍,写多线程C时你会自然追问"这把锁归谁、这个buffer现在谁在写"。这比单纯防悬垂更值钱。
你后来C还写得多吗,还是新东西直接上Rust了?