Himuraの技术小站
首页项目归档照片墙音乐说说
账户
Rust 入门:所有权、借用与无畏并发 封面

Rust 入门:所有权、借用与无畏并发

写作时间:2026-05-27
# Rust

Rust 没有 GC,又不用你手动 free,全靠编译期那套「所有权」撑着。刚上手那阵我天天跟借用检查器吵架,但把所有权搞明白之后,它的大部分脾气也就理解了。

规则其实就三条:一个值只有一个主人;同一时间只能有一个主人;主人一离开作用域,值就自动清掉。听着简单,写起来照样翻车:

let s1 = String::from("hello");
let s2 = s1;          // 所有权搬到 s2 了
// println!("{}", s1); // 编译不过,s1 已经「空」了

第一次撞上这报错的人基本都懵——我就赋了个值,怎么原来那个就不能用了?因为 Rust 里这种类型的 = 是「移动」,不是「拷贝」。

借用:借来用一下,不抢所有权

不想转移所有权,那就借:

fn len(s: &String) -> usize { s.len() }  // 借个只读的

let s = String::from("hi");
println!("{}", len(&s));  // s 还是自己的

借用检查器盯得最死的一条:要么一堆只读借用,要么一个可写借用,不能又读又写。这条乍看挺烦,其实就是在编译期帮你把数据竞争堵死了——大家一起读没事,有人要写就不许别人插手。

let mut v = vec![1, 2, 3];
let r1 = &v;       // 行
let r2 = &v;       // 行,只读随便借
// let m = &mut v; // 不行,前面还有只读借用没还呢

多线程:Arc 配 Mutex

跨线程共享一个可变的东西,标配就是 Arc(共享所有权)加 Mutex(加锁):

use std::sync::{Arc, Mutex};
use std::thread;

let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];

for _ in 0..10 {
    let c = Arc::clone(&counter);
    handles.push(thread::spawn(move || {
        let mut n = c.lock().unwrap();
        *n += 1;
    }));
}
for h in handles { h.join().unwrap(); }
println!("结果 = {}", *counter.lock().unwrap()); // 10

你要是忘了加锁、想直接跨线程改数据——放心,编译器根本不让你过。所谓「无畏并发」就是这意思:能编译过的并发代码,一大类低级错误它已经替你拦掉了。

刚开始所有权是真磨人,逼着你每写一行都想想这数据归谁、能活多久。但熬过那阵就会发现,好多并发的坑你压根没机会踩。

评论

登录 后参与评论。

还没有评论。

avatar

Himura

这里收集 Web 开发、工具项目、音视频处理与生活灵感,也记录踩坑复盘和作品更新。希望每一篇内容都能沉淀一点经验,留下值得回看的技术轨迹。

RECOMMENDED

竞拍之王计算器使用须知

2026-05-30

React 渲染优化:别让组件做无用功

2026-05-19

TypeScript 类型实战:少写 any,让类型替你兜底

2026-05-12

Table of Contents