一句话总结:把命名拆成「前缀 + 动词」就能立刻知道函数会不会拿走所有权、会不会分配内存、会不会失败。
1. 一张图记住所有模式
| 前缀 | 所有权 | 开销 | 返回值 | 例子 | 一句话记忆 |
|---|---|---|---|---|---|
new | ‑ | 不定 | Self | Vec::new() | 造个新的 |
default | ‑ | 不定 | Self | String::default() | 按规矩造个新的 |
with_ | ‑ | 不定 | Self | Vec::with_capacity(10) | 带点配置造个新的 |
from_ | ‑ | 不定 | Self | String::from("hi") | 把 A 变 Self |
into_ | 消耗 | 不定 | 别的类型 | vec.into_boxed_slice() | 把 Self 变成 B |
to_ | 保留 | 可能高 | 别的类型 | 42.to_string() | 克隆一份再变成 B |
as_ | 保留 | 极低 | 引用 / 原始类型 | s.as_str() | 免费看一眼,零拷贝 |
try_to/into/from | 保留/消耗/消耗 | 不定 | Result<T, E> | s.try_into::<i32>() | 可能失败版 to/into/from |
get_ | 保留 | 极低 | 内部引用 | map.get("k") | 只借不拿 |
set_ | 可变 | 极低 | () | buf.set_len(5) | 改内部状态 |
is_/has_ | 保留 | 极低 | bool | opt.is_some() | 问个 yes/no |
2. 廉价 vs 昂贵:一眼识别性能热点
| 廉价(放心用) | 昂贵(注意调用频率) |
|---|---|
as_str() | to_string() |
len() | clone() |
is_empty() | String::from("…") |
slice[1..] | fs::read_to_string("…") |
规则:只要看到
to_/into_/from_/new/clone,先想一想是不是在热路径里。
3. 组合示例:30 秒写健壮的类型转换
// 1. 零开销查看
let s = String::from("123");
let r: &str = s.as_str(); // 廉价,无 alloc
// 2. 可能失败的转换
let n: i32 = s.parse()?; // 等价 try_into,返回 Result
// 3. 消耗所有权,避免二次分配
let bytes: Vec<u8> = s.into_bytes(); // 昂贵但只做一次
4. 团队规范一句话
代码评审时只问三个问题:
- 前缀对吗?
- 所有权清了吗?
- 在热路径里会不会放大 O(n)?
附录:速查口令
“
as_看一眼,to_克隆走,into_拿走不回头;try_小心摔跟头。”