一句话总结:把命名拆成「前缀 + 动词」就能立刻知道函数会不会拿走所有权、会不会分配内存、会不会失败。
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 秒写健壮的类型转换
rust
// 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_
小心摔跟头。"